繁体   English   中英

PHP 如何通过关联键值对多维数组进行分组

[英]PHP How to Group Multidimensional Array by associative Key Value

我有这个当前的 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)

我想将所有 arrays 与类似'year_and_filling_date'合并,并将所有属性'total_revenue''net_income''net_cash_ending_balance''long-term_debt'

我不知道从哪里开始,

我正在考虑循环进入每个数组以获得唯一的“year_and_filing_date”

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

结果是['2019','2020'];

然后进行另一个循环以过滤$newData结果['2019','2020']

我期待得到两个不同的 arrays,一个返回 1 个结果,另一个返回 2 个结果,

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

你不需要过滤,你可以检查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");        
    }
}

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

$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);

对 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',
        ]
];

该算法可以很容易地写为 function。

$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,
  ),
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM