如何对重复数据的数组值求和

时间:2016-09-01 07:43:01

标签: php arrays json sum grouping

我有一个数组具有相同的ID值,如下所示。

[
    {"ID":"126871","total":"200.00","currency":"USD","name":"John"},
    {"ID":"126872","total":"2000.00","currency":"Euro","name":"John"},
    {"ID":"126872","total":"1000.00","currency":"Euro","name":"John"},
    {"ID":"126872","total":"500.00","currency":"USD","name":"John"},
    {"ID":"126872","total":"1000.00","currency":"Euro","name":"John"},
]

如果ID值重复,请将相同currency的总值相加。对于同一currency的不同ID,无需求total

这就是我想要的。

[
    {"ID":"126871","total":"200.00","currency":"USD","name":"John"},
    {"ID":"126872","total":"4000.00","currency":"Euro","name":"John"},
    {"ID":"126872","total":"500.00","currency":"USD","name":"John"}
]

我遇到了上述问题。我已经尽力了。但是我得到了错误的结果。我非常感谢任何建议。

5 个答案:

答案 0 :(得分:2)

@Cloud我已根据您的要求提供了功能,并感谢@M。 I.查看这个总和部分。

$array = array(
    array("ID"  => "126871","total"=>"200.00","currency"=>"USD","name"=>"John"),
    array("ID"  => "126872","total"=>"2000.00","currency"=>"Euro","name"=>"John"),
    array("ID"  => "126872","total"=>"1000.00","currency"=>"Euro","name"=>"John"),
    array("ID"  => "126872","total"=>"500.00","currency"=>"USD","name"=>"John"),
    array("ID"  => "126872","total"=>"1000.00","currency"=>"Euro","name"=>"John"),
);
echo "<pre>";
print_r($array);

function unique_multidim_array($array, $key,$key1,$addedKey) { 
    $temp_array = array(); 
    $i = 0; 
    $key_array = array(); 
    $key1_array = array(); 

    foreach($array as $val) { 
        if (!in_array($val[$key], $key_array) && !in_array($val[$key1], $key1_array)) { 
            $key_array[$i] = $val[$key]; 
            $key1_array[$i] = $val[$key1]; 
            $temp_array[$i] = $val; 
        }else{
            $pkey = array_search($val[$key],$key_array);
            $pkey1 = array_search($val[$key1],$key1_array);
            if($pkey==$pkey1){
                $temp_array[$pkey][$addedKey] += $val[$addedKey];
            }else{
                $key_array[$i] = $val[$key]; 
                $key1_array[$i] = $val[$key1]; 
                $temp_array[$i] = $val; 
            }
            // die;
        }
        $i++; 
    } 
    return $temp_array; 
} 

$nArray = unique_multidim_array($array,"ID","currency","total");
// die;
print_r($nArray);
die;

答案 1 :(得分:1)

@Cloud试试这个。

$array = array(array("ID"   => "126871","total"=>"200.00","currency"=>"USD","name"=>"John",),array("ID" => "126871","total"=>"200.00","currency"=>"USD","name"=>"John",),array("ID" => "126872","total"=>"1000.00","currency"=>"Euro","name"=>"John",));
    echo "<pre>";
    print_r($array);
    $unique = array_map('unserialize', array_unique(array_map('serialize', $array)));

当然是@Magnus Eriksson。我在解释为​​什么我们在步骤中使用'serialize'和'unserialize':

步骤1:将多维数组转换为一维数组

要将多维数组转换为一维数组,首先要生成数组内所有元素(包括嵌套数组)的字节流表示。 serialize()函数可以生成一个值的字节流表示。要生成所有元素的字节流表示,请在serialize()函数内调用array_map()函数作为回调函数。无论多维数组有多少级别,结果都将是一维数组。

第2步:使值唯一

要使这个一维数组唯一,请使用array_unique()函数。

第3步:将其还原为多维数组

虽然数组现在是唯一的,但值看起来像字节流表示。要将其还原为多维数组,请使用unserialize()函数。

我希望现在为什么要制作这段代码。

答案 2 :(得分:0)

内容:创建按&#39; ID&#39;分组的数组和货币&#39;。累计重复货币。

如何:

  • 一次向输出数组添加一行。
  • 如果组不在数组中,则添加
  • 如果它在数组中,则将货币添加到现有记录中。

Demonstration at eval.in

代码:

sed -e $'/TOREPLACE/{;z;r/dev/stdin\n}' file.txt <<<"$TEST"

运行它:

/** ----------------------------------------------
* Create an output array one row at a time.
* 
* Group by Id and currency.   
* 
* @param array $groups
* 
* @return array
*/
function getCurrencyGroups(array $groups)
{
    $currencyGroups = array();

    foreach ($groups as $item) {

        $id       = $item['ID'];
        $currency = $item['currency'];
        $amount   = $item['total'];

        if (!isset($currencyGroups[$id][$currency])) {
            $currencyGroups[$id][$currency] = $amount;
        }
        else {
            $currencyGroups[$id][$currency] += $amount;
        }
    }

    return $currencyGroups;
}

输出:

$currencyGroups = getCurrencyGroups($source);

答案 3 :(得分:0)

您需要:

  • 使用json_decode将您的json字符串转换为php数组。
  • 遍历行并使用复合临时键对它们进行分组。换句话说,从每行的ID&amp;行生成一个字符串。 currency值并将该字符串用作临时唯一键。
  • 对分组行的total值求和。
  • 然后通过重新索引行并调用json_encode()来准备输出数组以返回json。

代码:(Demo

$json='[
    {"ID":"126871","total":"200.00","currency":"USD","name":"John"},
    {"ID":"126872","total":"2000.00","currency":"Euro","name":"John"},
    {"ID":"126872","total":"1000.00","currency":"Euro","name":"John"},
    {"ID":"126872","total":"500.00","currency":"USD","name":"John"},
    {"ID":"126872","total":"1000.00","currency":"Euro","name":"John"}
]';

$array=json_decode($json,true);  // convert to array
foreach($array as $row){
    if(!isset($result[$row['ID'].$row['currency']])){
        $result[$row['ID'].$row['currency']]=$row;  // on first occurrence, store the full row
    }else{
        $result[$row['ID'].$row['currency']]['total']+=$row['total'];  // after first occurrence, add current total to stored total
    }
}
$result=json_encode(array_values($result));  // reindex the array and convert to json
echo $result;  // display

输出:

[
    {"ID":"126871","total":"200.00","currency":"USD","name":"John"},
    {"ID":"126872","total":4000,"currency":"Euro","name":"John"},
    {"ID":"126872","total":"500.00","currency":"USD","name":"John"}
]

答案 4 :(得分:0)

我发现自己处于类似的情况,除了我将自己画在一个角落,需要使用相同的数组进行输入和输出。我还发现Manish的反应有些笨拙。

foreach($open_po_report as $pkey => &$po_line){
    foreach($open_po_report as $dkey => $dupe_item){
        //do not compare the exact same line
        if($dupe_item['PoNo'].$dupe_item['Line'] === $po_line['PoNo'].$po_line['Line']){
            continue;
        }
        //once you find a duplicate sum the qty to the original occurance
        if($dupe_item['ItemVendorItem'] === $po_line['ItemVendorItem']){
            $po_line['MyOrder']+=$dupe_item['MyOrder'];
            unset($open_po_report[$dkey]);
        }
        //delete the duplicate entry
    }
}