I have an array with some of same ID
value as shown in below.
[
{\"ID\":\"126871\",\"total\":\"200.00\",\"currency\":\"USD\",\"name\":\"John
@Cloud Try this.
$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)));
Sure @Magnus Eriksson. I am explaining why we use 'serialize' and 'unserialize' in steps :
Step 1: Convert the multidimensional array to one-dimensional array
To convert the multidimensional array to a one-dimensional array, first generate byte stream representation of all the elements (including nested arrays) inside the array. serialize() function can generate byte stream representation of a value. To generate byte stream representation of all the elements, call serialize() function inside array_map() function as a callback function. The result will be a one dimensional array no matter how many levels the multidimensional array has.
Step 2: Make the values unique
To make this one dimensional array unique, use array_unique() function.
Step 3: Revert it to the multidimensional array
Though the array is now unique, the values looks like byte stream representation. To revert it back to the multidimensional array, use unserialize() function.
I hope now why i make this code.
I found myself in a similar situation except for I painted myself into a corner and needed to use the same array for input and output. I also found Manish response to be a little heavy-handed.
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
}
}
@Cloud I have made function for your requirement and Thanks @M. I. for look into this sum section.
$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;
What: Create an array that is grouped by 'ID' and 'Currency'. Accumulate currency for duplicates.
How:
Demonstration at eval.in
Code:
/** ----------------------------------------------
* 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;
}
Run it:
$currencyGroups = getCurrencyGroups($source);
Output:
array (size=2)
126871 =>
array (size=1)
'USD' => string '200.00' (length=6)
126872 =>
array (size=2)
'Euro' => float 4000
'USD' => string '500.00' (length=6)
You will need to:
json_decode
.ID
& currency
values and use that string as the temporary unique key.total
values.json_encode()
.Code: (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
Output:
[
{"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"}
]