按列对二维数组的行进行分组,并对每组中的其他列进行求和

问题描述 投票:0回答:3

我有当前的 PHP 数组

$newData = array (size=3)
    0 => 
      array (size=6)
        'company_name' => string 'CO 1' (length=32)
        'year_and_filing_date' => string '2019' (length=4)
        'total_revenue' => string '200' (length=3)
        'net_income' => string '300' (length=3)
        'net_cash_ending_balance' => string '150' (length=3)
        'long-term_debt' => string '210' (length=3)
    1 => 
      array (size=6)
        'company_name' => string 'CO 1' (length=32)
        'year_and_filing_date' => string '2020' (length=4)
        'total_revenue' => string '200' (length=3)
        'net_income' => string '300' (length=3)
        'net_cash_ending_balance' => string '150' (length=3)
        'long-term_debt' => string '210' (length=3)
    2 => 
      array (size=6)
        'company_name' => string 'CO 1' (length=32)
        'year_and_filing_date' => string '2020' (length=4)
        'total_revenue' => string '100' (length=3)
        'net_income' => string '200' (length=3)
        'net_cash_ending_balance' => string '50' (length=2)
        'long-term_debt' => string '110' (length=3)

我想合并所有具有相似

'year_and_filling_date'
的数组并对所有数组求和 属性
'total_revenue'
'net_income'
'net_cash_ending_balance'
'long-term_debt'

我不知道从哪里开始,

我正在考虑循环每个数组以获得唯一的 '年份和申请日期'

$unique_years = array_unique(
   array_map(function($elem){
      return $elem['year_and_filing_date'];
   },
   $newData)
);

结果是

['2019','2020'];

然后再做一个循环来过滤

$newData
,结果为
['2019','2020']

我期望得到两个不同的数组, 一个返回 1 个结果,另一个返回 2 个结果,

但是我如何只对选定的字段求和?

php arrays multidimensional-array sum grouping
3个回答
1
投票

不需要过滤,可以检查foreach循环中是否存在今年的记录

$result = [];
foreach ($newData as $row) {
    $year = $row['year_and_filing_date'];
    if(!isset($result[$year])) {
        $result[$year]['total_revenue'] = $row['total_revenue'];
        $result[$year]['net_income'] = $row['net_income'];
        $result[$year]['net_cash_ending_balance'] = $row['net_cash_ending_balance'];
        $result[$year]['long-term_debt'] = $row['long-term_debt'];
        $result[$year]['last_scraped'] = date("Y-m-d h:i:s");
    } else {
        $result[$year]['total_revenue'] += $row['total_revenue'];
        $result[$year]['net_income'] += $row['net_income'];
        $result[$year]['net_cash_ending_balance'] += $row['net_cash_ending_balance'];
        $result[$year]['long-term_debt'] += $row['long-term_debt'];
        $result[$year]['last_scraped'] = date("Y-m-d h:i:s");        
    }
}

0
投票

这就是我到目前为止所做的, 它正在工作,但尚未优化, 我希望有人可以改进我的代码,

$newData = [];

/* Transform the Filling Date to Year */
array_walk($data, 
    function ($item2, $key) use (&$newData)
    {
        foreach($item2 as $keyAssoc => $val)
        {
            if($keyAssoc == 'year_and_filing_date')
            {
                if(!empty($val))
                {
                    $newData[$key][$keyAssoc] = date("Y", strtotime(date("d/m/Y", strtotime($val))));
                }
            }else{
                $newData[$key][$keyAssoc] = $val;
            }
        }
    }
);

/* Group Data by Years and Sum Up */
if(count($newData)>0)
{
    /* Get Unique Years */
    $unique_years = array_unique(array_map(function($elem){return $elem['year_and_filing_date'];}, $newData));
    asort($unique_years);

    $consolidatedData = [];
    foreach($unique_years as $key => $val)
    {
        foreach($newData as $k => $propertyName)
        {
            /* Compare if Year is Matching */
            if($propertyName['year_and_filing_date'] == $val)
            {
                
                $filteredData = array_filter($consolidatedData, function ($item) use ($val){
                    return $item['year_and_filing_date'] === $val;
                });

                /* Already Exists */
                if(count($filteredData)>0)
                {
                    $consolidatedData[$val]['company_name'] = $propertyName['company_name'];
                    $consolidatedData[$val]['year_and_filing_date'] = $val;
                    $total_revenue_raw = $filteredData[$val]['total_revenue'] + $propertyName['total_revenue'];
                    $consolidatedData[$val]['total_revenue'] = (string) $total_revenue_raw;
                    $net_income_raw = $filteredData[$val]['net_income'] + $propertyName['net_income'];
                    $consolidatedData[$val]['net_income'] = (string) $net_income_raw;
                    $net_cash_ending_balance_raw = $filteredData[$val]['net_cash_ending_balance'] + $propertyName['net_cash_ending_balance'];
                    $consolidatedData[$val]['net_cash_ending_balance'] = (string) $net_cash_ending_balance_raw;
                    $long_debt_raw = $filteredData[$val]['long-term_debt'] + $propertyName['long-term_debt'];
                    $consolidatedData[$val]['long-term_debt'] = (string) $long_debt_raw;
                    $consolidatedData[$val]['source_url'] = $propertyName['source_url'];
                    $consolidatedData[$val]['last_scraped'] = date("Y-m-d h:i:s");
                }else{
                    $consolidatedData[$val]['company_name'] = $propertyName['company_name'];
                    $consolidatedData[$val]['year_and_filing_date'] = $val;
                    $consolidatedData[$val]['total_revenue'] = $propertyName['total_revenue'];
                    $consolidatedData[$val]['net_income'] = $propertyName['net_income'];
                    $consolidatedData[$val]['net_cash_ending_balance'] =$propertyName['net_cash_ending_balance'];
                    $consolidatedData[$val]['long-term_debt'] = $propertyName['long-term_debt'];
                    $consolidatedData[$val]['source_url'] = $propertyName['source_url'];
                    $consolidatedData[$val]['last_scraped'] = date("Y-m-d h:i:s");
                }
            }
        }
    }
}

return var_dump($consolidatedData);

0
投票

对 alibek.gao 的解决方案进行了轻微修改。

输入:

$newData = [
       ['company_name' => 'CO 1' , 'year_and_filing_date' => '2019', 'total_revenue' => '200',
        'net_income' => '300' , 'net_cash_ending_balance' => '150' ,  'long-term_debt' =>  '210'
       ],
       ['company_name' => 'CO 1', 'year_and_filing_date' => '2020', 'total_revenue' => '200',
        'net_income' => '300','net_cash_ending_balance' => '150',   'long-term_debt' => '210'
       ],
        ['company_name' => 'CO 1', 'year_and_filing_date' =>'2020',  'total_revenue' => '100',
        'net_income' => '200', 'net_cash_ending_balance' => '50',   'long-term_debt' => '110',
        ]
];

该算法可以轻松地编写为函数。

$aggregateSum = ['total_revenue','net_income','net_cash_ending_balance','long-term_debt'];

$groupBy = 'year_and_filing_date';

$result = [];
foreach ($newData as $row) {
    $year = $row[$groupBy];
    if(!isset($result[$year])) {
        $result[$year] = $row;
    } else {
        foreach($aggregateSum as $field){
          $result[$year][$field] += $row[$field];
        }
    }
}

此解决方案保留非总计字段:

结果:

array (
  2019 => 
  array (
    'company_name' => "CO 1",
    'year_and_filing_date' => "2019",
    'total_revenue' => "200",
    'net_income' => "300",
    'net_cash_ending_balance' => "150",
    'long-term_debt' => "210",
  ),
  2020 => 
  array (
    'company_name' => "CO 1",
    'year_and_filing_date' => "2020",
    'total_revenue' => 300,
    'net_income' => 500,
    'net_cash_ending_balance' => 200,
    'long-term_debt' => 320,
  ),
)
© www.soinside.com 2019 - 2024. All rights reserved.