Sum values in Multiple Dimensional array that have same key value - php

i have a Multiple Dimensional array and i need to sum up values which have the same keys .
print_r($inputs)
Array
(
[0] => Array
(
[id] => colors
[power] => Array
(
[green] => 12
[red] => 5
[orange] => 9
[black] => 6
[white] => 5
[blue] => 11
)
)
[1] => Array
(
[id] => colors
[power] => Array
(
[green] => 20
[red] => 40
[orange] => 80
[black] => 60
[white] => 100
[blue] => 110
)
)
[2] => Array
(
[id] => glossycolor
[power] => Array
(
[green] => 20
[red] => 40
[orange] => 80
[black] => 60
[white] => 100
[blue] => 110
)
)
)
i need the result to be like
Array
(
[0] => Array
(
[id] => colors
[power] => Array
(
[green] => 32
[red] => 45
[orange] => 89
[black] => 66
[white] => 105
[blue] => 121
)
)
[1] => Array
(
[id] => glossycolor
[power] => Array
(
[green] => 20
[red] => 40
[orange] => 80
[black] => 60
[white] => 100
[blue] => 110
)
)
)
i tried to use array_shift to sort the values and sum the sub array values but i failed
$finalRate = array_shift($inputs);
foreach ($inputs as $val) {
foreach ($val as $key => $val) {
$finalRate[$key] += $val;
}
}
but failed and return empty array .

Assuming your arrays have always the same structure I'd go with:
$outcome = array();
foreach ($colors as $array) {
$id = $array['id'];
if (array_key_exists($id, $outcome)) {
foreach ($array['power'] as $color => $value) {
$outcome[$id]['power'][$color] += $value;
}
continue;
}
$outcome[$array['id']] = $array;
}
array_values($outcome);

$array1 = array_slice($input,0,1); //slicing first value of $input i.e Array([0]=>array)
$array2 = array_slice($input,1,1); //slicing second value of $input i.e Array([1]=>array)
$array = array_sum_values($array1,$array2); //summing values of two arrays
$input = array_splice($input,0,2,$array) //Removing [0] and [1] from $input and replacing with $array.
Please refer PHP manual for more details.

This probably isn't the most efficient way for going about this.. but it works and was easy to implement:
$arr = array(
0 => array(
'id' => 'colors',
'power' => array(
'green' => 12,
'red' => 5,
'orange' => 9,
'black' => 6,
'white' => 5,
'blue' => 11,
),
),
1 => array(
'id' => 'colors',
'power' => array(
'green' => 20,
'red' => 40,
'orange' => 80,
'black' => 60,
'white' => 100,
'blue' => 110,
),
),
2 => array(
'id' => 'glossycolors',
'power' => array(
'green' => 20,
'red' => 40,
'orange' => 80,
'black' => 60,
'white' => 100,
'blue' => 110,
),
),
);
foreach ( $arr as $k1 => $v1 ) {
foreach ( $arr as $k2 => $v2 ) {
if ( $k1 === $k2 ) continue;
if ( ! isset( $arr[ $k1 ] ) || ! isset( $arr[ $k2 ] ) ) continue;
if ( $v1['id'] === $v2['id'] ) {
foreach ( $v2['power'] as $power_k => $power_v ) {
$arr[$k1]['power'][$power_k] += $power_v;
}
unset( $arr[$k2] );
}
}
}
print_r( $arr );
And this results in:
Array
(
[0] => Array
(
[id] => colors
[power] => Array
(
[green] => 32
[red] => 45
[orange] => 89
[black] => 66
[white] => 105
[blue] => 121
)
)
[2] => Array
(
[id] => glossycolors
[power] => Array
(
[green] => 20
[red] => 40
[orange] => 80
[black] => 60
[white] => 100
[blue] => 110
)
)
)
So basically, it loops through the same array twice and sums the values of common 'id' elements, then removes the second copy from the array leaving only the original with the sum of the later. Cheers

Related

Merge 2 Arrays on second level with different keys

I need to merge two arrays on the second level with different key names but the same amount of keys.
usera=102
userb=103
My desired output would be array 3.
I have tried a lots of variations to get this together.
My best attempt was something like the following but it destroyed my key names:
$results = array();
foreach($arr1 as $key => $array)
{
foreach($array as $user => $value)
{
$results[$user]['name'] = $value;
}
}
foreach($arr2 as $key => $array)
{
foreach($array as $user => $value)
{
$results[$user]['name2'] = $value;
}
}
Array 1 :
Array
(
[usera] => Array
(
[0] => Array
(
[user] => usera
[duration_s] => 15
)
[1] => Array
(
[user] => usera
[duration_s] => 9
)
)
[userb] => Array
(
[2] => Array
(
[user] => userb
[duration_s] => 21
)
[3] => Array
(
[user] => userb
[duration_s] => 19
)
)
)
Array 2:
Array
(
[102] => Array
(
[0] => Array
(
[user] => 102
[duration_s2] => 54
)
[1] => Array
(
[user] => 102
[duration_s2] => 378
)
)
[103] => Array
(
[2] => Array
(
[usernr] => 103
[duration_s2] => 299
)
[3] => Array
(
[usernr] => 103
[duration_s2] => 110
)
)
)
Array 3:
Array
(
[usera] => Array
(
[0] => Array
(
[user] => usera
[duration_s] => 15
[usernr] => 102
[duration_s2] => 54
)
[1] => Array
(
[user] => usera
[duration_s] => 9
[usernr] => 102
[duration_s2] => 378
)
)
[userb] => Array
(
[2] => Array
(
[user] => userb
[duration_s] => 21
[usernr] => 103
[duration_s2] => 299
)
[3] => Array
(
[user] => userb
[duration_s] => 19
[usernr => 103
[duration_s2] => 110
)
)
)
Try the following code using array_values() :
<?php
$array1 = [
'usera' => [
0=> ['user' => 'usera','duration_s' => 15],
1=> ['user' => 'usera','duration_s' => 9],
],
'userb' => [
2=> ['user' => 'usera','duration_s' => 15],
3=> ['user' => 'usera','duration_s' => 9],
],
];
$array2 = [
102 => [
0=> ['usernr' => 102,'duration_s2' => 54],
1=> ['usernr' => 102,'duration_s2' => 378]
],
103 => [
2=> ['usernr' => 103,'duration_s2' => 299],
3=> ['usernr' => 103,'duration_s2' => 110]
],
];
$array2 = array_values($array2);
$array1 = array_values($array1);
foreach($array1 as $index=>$ar1){
foreach ($ar1 as $index2=>$ar2){
$array1[$index][$index2] = array_merge($ar2,$array2[$index][$index2]);
}
}
print_r($array1);
To merge the array you can also do the following :
$index = 0;
foreach ($arr2 as $key => $value) { // changing the indexing of second array
$arr3[$index] = $value;
$index++;
}
$results = array();
$count = 0;
foreach ($arr1 as $index => $value) { // merging two array
$total = 0;
foreach ($value as $key => $val) {
$merge_value = array_merge($val,$arr3[$count][$total]);
$results[$index][$total] = $merge_value;
$total++;
}
$count++;
}
print_r($results);
In this result your indexing will not lost.

Remove the top level array and merge sub array into one

I have a multidimensional array and I want to remove the top level array and merge all its sub array into one array.
Below is my array:
$arr = [KEY1] => Array
(
[0] => Array
(
[Feb] => 120
)
[1] => Array
(
[Jan] => 230
)
[3] => Array
(
[Mar] => 340
)
)
[KEY2] => Array
(
[0] => Array
(
[Feb] => 12
)
[1] => Array
(
[Jan] => 23
)
[3] => Array
(
[Mar] => 34
)
)
I need to arrange and sort this array like below:
Output:
[KEY1] => Array
(
[Jan] => 230,
[Feb] => 120,
[Mar] => 340
)
[KEY2] => Array
(
[Jan] => 23,
[Feb] => 12,
[Mar] => 34
)
I have used
call_user_func_array('array_merge', $arr ); but not working.
Please suggest any wise way to do this.
Thanks
You can try like this as simple way,
$arr = [
'key1' =>[
0 => ["feb" => 123],
1 => ["dev" => 213],
2 => ["jan" => 111],
],
'key2' =>[
0 => ["feb" => 132],
1 => ["dev" => 321],
2 => ["jan" => 555],
],
];
$result = [];
foreach($arr as $k => $v){
foreach($v as $k1 => $v1){
foreach($v1 as $k2 => $v2)
$result[$k][$k2] = $v2;
}
}
print_r($result);
Hope this will solve your problem.
EDIT
Here is your sorting function.
function sortNestedArray(&$a)
{
sort($a);
for ($i = 0; $i < count($a); $i++) {
if (is_array($a[$i])) {
sortNestedArray($a[$i]);
}
}
return $a;
}
$a = sortNestedArray($result);
print_r($a);

Php count duplicate elements in an array and concat of ids

How can we find the count of duplicate elements in a multidimensional array and concat of ids ?
I have an array of skill names with feed ids. I need to count skill name and concat of feed ids.
Array
(
[0] => Array
(
[skill_name] => PHP
[feed_id] => 100
)
[1] => Array
(
[skill_name] => CSS
[feed_id] => 105
)
[2] => Array
(
[skill_name] => Php
[feed_id] => 110
)
[3] => Array
(
[skill_name] => Php
[feed_id] => 111
)
[4] => Array
(
[skill_name] => CSS
[feed_id] => 112
)
[5] => Array
(
[skill_name] => Javascript
[feed_id] =>114
)
}
Output should be like below.
Array
(
[0] => Array
(
[skill_name] => PHP
[feed_id] => 100, 110, 111
[count]=>3
)
[1] => Array
(
[skill_name] => CSS
[feed_id] => 105, 112
[count]=>2
)
[2] => Array
(
[skill_name] => Javascript
[feed_id] => 114
[count]=>1
)
}
Thanks in advance!!
//Assumption: Input is in $in
//Step 1: Cumulate
$tmp=array();
foreach ($in as $skill) {
if (isset($tmp[$skill['skill_name']]))
$tmp[$skill['skill_name']][]=$skill['feed_id'];
else
$tmp[$skill['skill_name']]=array($skill['feed_id']);
}
//Step 2: Fix up desired output format
$out=array();
foreach ($tmp as $k=>$v)
$out[]=array(
'skill_name' => $k,
'feed_id' => implode(', ', $v),
'count' => sizeof($v)
);
//Result is in $out
This is perfectly achievable with a single loop using temporary keys and simple concatenation and incrementation.
Code: (Demo)
$array = [
['skill_name' => 'PHP', 'feed_id' => 100],
['skill_name' => 'CSS', 'feed_id' => 105],
['skill_name' => 'Php', 'feed_id' => 110],
['skill_name' => 'Php', 'feed_id' => 111],
['skill_name' => 'CSS', 'feed_id' => 112],
['skill_name' => 'Javascript', 'feed_id' => 114]
];
foreach ($array as $row) {
$upperSkill = strtoupper($row['skill_name']);
if (!isset($result[$upperSkill])) {
$result[$upperSkill] = $row + ['count' => 1]; // plus acts as array_merge here
} else {
$result[$upperSkill]['feed_id'] .= ",{$row['feed_id']}"; // concatenate
++$result[$upperSkill]['count']; // increment
}
}
var_export(array_values($result)); // reindex and display
Output:
array (
0 =>
array (
'skill_name' => 'PHP',
'feed_id' => '100,110,111',
'count' => 3,
),
1 =>
array (
'skill_name' => 'CSS',
'feed_id' => '105,112',
'count' => 2,
),
2 =>
array (
'skill_name' => 'Javascript',
'feed_id' => 114,
'count' => 1,
),
)

unique array on base on value of specific key

I have the following array:
Array
(
[0] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 2
)
[1] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 3
)
[2] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 4
)
[3] => Array
(
[hotelID] => 14
[hotelcategoryID] => 7
[hotelName] => Hotel Metropolis
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 23
)
[4] => Array
(
[hotelID] => 14
[hotelcategoryID] => 7
[hotelName] => Hotel Metropolis
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 24
)
)
I have two different hotelID keys. I would like to extract only one element (the first one) where the hotelID is unique in whole array. I am trying with following code:
$data['uniqueHotels'] = array_map('unserialize', array_unique(array_map('serialize', $hotels)));
but without any luck so far.
Anyone can give me a hint?
If looking for the first element:
<?php
$hotels = array(
array(
'id' => 1,
'hotelID' => 10
),
array(
'id' => 2,
'hotelID' => 10,
),
array(
'id' => 3,
'hotelID' => 20,
),
array(
'id' => 4,
'hotelID' => 20,
),
);
function getUniqueHotels($hotels) {
$uniqueHotels = array();
foreach($hotels as $hotel) {
$niddle = $hotel['hotelID'];
if(array_key_exists($niddle, $uniqueHotels)) continue;
$uniqueHotels[$niddle] = $hotel;
}
return $uniqueHotels;
}
$unique_hotels = getUniqueHotels($hotels);
print_r($unique_hotels);
results in:
Array
(
[10] => Array
(
[id] => 1
[hotelID] => 10
)
[20] => Array
(
[id] => 3
[hotelID] => 20
)
)
You could simply loop through the array and add them to a new array, indexed by hotelID. This way any duplicates will just overwrite the existing value and you end up with one entry per hotel:
$unique = array();
foreach ($hotels as $value)
{
$unique[$value['hotelID']] = $value;
}
$data['uniqueHotels'] = array_values($unique);
Here is a dynmaic solution:
function uniqueAssocArray($array, $uniqueKey){
$unique = array();
foreach ($array as $value){
$unique[$value[$uniqueKey]] = $value;
}
$data = array_values($unique);
return $data;
}
How to use:
uniqueAssocArray($yourArray, 'theKey');
along the lines of what you're trying,
array_unique(array_map(function($hotel) { return $hotel['hotelID']; }, $array))

Searching for a value inside an array and getting the array

I am trying to use an array to search for a value that is inside of an array and then take the full array that the value is in and add it to an array. Below is the array to get the value from:
Array (
[0] => Array ( [ID] => 138 [dimmer] => 5 [order] => 1 [double] => 0 [location1] => DSR [location2] => Stage Pockets )
[1] => Array ( [ID] => 139 [dimmer] => 6 [order] => 1 [double] => 0 [location1] => DSR [location2] => Stage Pockets )
[2] => Array ( [ID] => 140 [dimmer] => 7 [order] => 2 [double] => 0 [location1] => DSR [location2] => Stage Pockets )
[3] => Array ( [ID] => 141 [dimmer] => 8 [order] => 2 [double] => 0 [location1] => DSR [location2] => Stage Pockets )
)
I am trying to get the value of dimmer with the search function below:
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value));
}
return $results;
}
Below it uses the $chan value which is an integer to use the function above to search an array. The foreach is then supposed to go through the array that is $patch and select the arrays out of the array above (only returns an empty array), although it doesn't do that unless you change $patch_single['dimmer'] with a string such as "7".
$patch = search($patch, 'Channel', $chan);
foreach ($patch as $patch_single) {
print_r($patch_single);
$dim_single = intval($patch_single['dimmer']);
echo $dim_single;
$dimmers = search($dimmers, 'dimmer', $dim_single);
}
The array that is being used to get $patch_single['dimmer'] is, when inside the foreach:
Array ( [ID] => 241 [Channel] => 100 [dimmer] => 7 )
Array ( [ID] => 242 [Channel] => 100 [dimmer] => 25 )
Thank you for your advice.
Hm, i see that you have 2 dimensional array. Why you just don't use this?
foreach($array as $row) {
if ($row['dimmer'] == $myValue) { $newArray[] = $row; }
}
Try this :
$arr = Array (Array ( "ID" => 138, "dimmer" => 5, "order" => 1, "double" => 0, "location1" => "DSR", "location2" => "Stage Pockets" ),
Array ( "ID" => 139, "dimmer" => 6, "order" => 1, "double" => 0, "location1" => "DSR", "location2" => "Stage Pockets" ),
Array ( "ID" => 140, "dimmer" => 7, "order" => 2, "double" => 0, "location1" => "DSR", "location2" => "Stage Pockets" ),
Array ( "ID" => 141, "dimmer" => 8, "order" => 2, "double" => 0, "location1" => "DSR", "location2" => "Stage Pockets" ));
$arr = array_filter($arr, function($ar) {
return ($ar['dimmer'] == '7' );
});
echo "<pre>";
print_r($arr);
Output :
Array
(
[2] => Array
(
[ID] => 140
[dimmer] => 7
[order] => 2
[double] => 0
[location1] => DSR
[location2] => Stage Pockets
)
)
ref: http://php.net/manual/en/function.array-filter.php

Categories