简体   繁体   中英

How to get sum of distinct key -> value in php arrays

I have the following string thatI convert into a json array. All I am trying to do put together keys with the same value for id_number and sum the amount to each of these keys and print the resulting value outside the loop.

$response = '{
               "nhif":[
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T20:18:50"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T19:59:14"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:07:34"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:04:27"
                  },
                  {
                     "id_number":"12345678",
                     "amount":"5",
                     "date":"2018-09-14T09:04:21"
                  }
               ]
            }';
$json_response = json_decode($response, true);

//Start NHIF
foreach ($json_response['nhif'] as $nhif) {
    echo ''.$nhif{"id_number"}.' '.$nhif{"amount"}.' '.$nhif{"date"}.'<br/>';
}
//END NHIF

My expected output is:

#id_number #amount
AA112233    20
12345678    5

Any workaround this?

You can use array_reduce to sum the amount values by id_number :

$sums = array_reduce($json_response['nhif'], function ($c, $i) { 
     $c[$i['id_number']] = (isset($c[$i['id_number']]) ? $c[$i['id_number']] : 0) + $i['amount']; 
     return $c; 
}, array());
print_r($sums);

Output:

AA112233    20
12345678    5

Demo on rextester

If you're using PHP7, this

isset($c[$i['id_number']]) ? $c[$i['id_number']] : 0

can be simplified to

$c[$i['id_number']] ?? 0

You can do solve this problem using an array

$response = '{
               "nhif":[
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T20:18:50"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T19:59:14"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:07:34"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:04:27"
                  },
                  {
                     "id_number":"12345678",
                     "amount":"5",
                     "date":"2018-09-14T09:04:21"
                  }
               ]
            }';
$json_response = json_decode($response, true);

$results = array();  // will map the unique keys with it's sum
//Start NHIF
foreach ($json_response['nhif'] as $nhif) {
    if(!isset($results[$nhif['id_number']]))  // new key initialized
        $results[$nhif['id_number']] = $nhif['amount'];
    else
        $results[$nhif['id_number']] += $nhif['amount'];
}
//END NHIF

foreach($results as $key => $value) {
    echo $key .' '.$value;  // printing the result
}
  1. Sort the array [If the data is not sorted otherwise do not need to sort].
  2. Do the for loop and summation.

Try with this code sample, there are many other ways to solve this problem depending on problem solving skill.

$response = '{
               "nhif":[
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T20:18:50"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T19:59:14"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:07:34"
                  },
                  {
                     "id_number":"AA112233",
                     "amount":"5",
                     "date":"2018-09-14T09:04:27"
                  },
                  {
                     "id_number":"12345678",
                     "amount":"5",
                     "date":"2018-09-14T09:04:21"
                  }
               ]
            }';
$data = json_decode($response, true);
usort($data['nhif'], function($a, $b) {
    return $b['id_number'] <=> $a['id_number'];
});

//Start NHIF
$amount = 0;
$id_number = null;
foreach($data['nhif'] as $nhif) {
    if(($nhif['id_number'] != $id_number) && ($id_number != null)){
        echo $id_number. "\t". $amount . "<br />";
        $id_number = $nhif['id_number'];
        $amount = $nhif['amount'];
    }
    else{
        $id_number = $nhif['id_number'];
        $amount = $amount + $nhif['amount'];
    }
    // echo ''.$nhif{"id_number"}.' '.$nhif{"amount"}.' '.$nhif{"date"}.'<br />';
}
echo $id_number. "\t". $amount . "<br />";
//END NHIF

You could create a new array for example $r and check if the key for $nhif['id_number'] already exists.

If it does, add value for $nhif['amount'] using += . If it does not, set the value using =

This example uses the ternary ?: operator:

$r = [];
foreach ($json_response['nhif'] as $nhif) {
    isset($r[$nhif['id_number']]) ? $r[$nhif['id_number']] += $nhif['amount'] : $r[$nhif['id_number']] = $nhif['amount'];
}

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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