我有当前的 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 个结果,
但是我如何只对选定的字段求和?
不需要过滤,可以检查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',
]
];
该算法可以轻松地编写为函数。
$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,
),
)