How to SUM and GROUP BY a multidimensional ARRAY by a key? - php

I have a multidimensional array and am trying to group by a value of one the keys.
So
Array (
[0] => Array (
[name] => Edward Foo
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 10
[1] => 20
[2] => 50
)
)
[1] => Array (
[name] => Michael Max
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 10
[1] => 10
[2] => 10
)
)
[2] => Array (
[name] => Edward Foo
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 5
[1] => 10
[2] => 30
)
)
[3] => Array (
[name] => Michael Max
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 8
[1] => 8
[2] => 20
)
)
And I really need:
Array (
[0] => Array (
[name] => Edward Foo
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 15
[1] => 30
[2] => 80
)
)
[1] => Array (
[name] => Michael Max
[desc_topic] => Array (
[0] => Apple
[1] => Banana
[2] => Orange
)
[qtd_posts] => Array (
[0] => 18
[1] => 18
[2] => 30
)
)
)

I'm assuming the following:
every name entry in the original array has an identical desc_topic sub-array (e.g. they all have the same Apple/Banana/Orange values for every instance.
the qtd_posts sub-array has the to-be-grouped values in the same corresponding slots (e.g. all '1' entries are to be summed together, all '2' entries summed together, etc...)
You want to preserve the parent array keys so that all 'Edward Foo' entries will use the first key used by an Edward Foo entry (e.g. 0)
If that applies, then something like this should work:
$newarr = array();
$reverse_map = array();
foreach($array as $idx => $entry) {
if (isset($reverse_map[$entry['name']]) {
// have we seen this name before? retrieve its original index value
$idx = $reverse_map[$entry['name']];
} else {
// nope, new name, so store its index value
$reverse_map[$entry['name']] = $idx;
}
// copy the 'constant' values
$newarr[$idx]['name'] = $entry['name'];
$newarr[$idx]['desc_top'] = $entry['desc_topic'];
// sum the qtd_post values to whatever we previously stored.
foreach($entry['qtd_posts'] as $x => $y) {
$newarr[$idx]['qtd_posts'][$x] += $y;
}
}

Related

Shifting array Values PHP

Please Help me. I have And Following array :
[0] => Array (
[0] => Name
[1] => Age
)
[1] => Array (
[0] => Name 1
[1] => 20
)
[2] => Array (
[0] => Name 2
[1] => 21
)
[3] => Array (
[0] => Name 3
[1] => 22
)
[4] => Array (
[0] => Name 4
[1] => 23
)
[5] => Array (
[0] => Name 5
[1] => 24
)
I want to achieve shift the values of array like this output:
Because when exporting excel file into php database values will insert incorrectly with shifting of 1 row of age:
[0] => Array (
[0] => Name
[1] => 20
)
[1] => Array (
[0] => Name 1
[1] => 21
)
[2] => Array (
[0] => Name 2
[1] => 22
)
[3] => Array (
[0] => Name 3
[1] => 23
)
[4] => Array (
[0] => Name 4
[1] => 24
)
[5] => Array (
[0] => Name 5
[1] => 25
)
Thanks In Advance.
You can also loop then check for the last array key
$array = [
["Name","Age"], ["Name 1","20"], ["Name 2","23"], ["Name 3","30"],
["Name 4","20"], ["Name 5","26"], ["Name 6","27"], ["Name 7","21"], ["Name 8","26"]
];
// Get last array key using count() or you can use end() then key()
$last_key = count($array) - 1;
$result = []; // initialize result array
foreach ($array as $key => $value) {
if ($key == $last_key) break; // if last key, break loop
$result[] = [ $array[$key][0], $array[++$key][1] ]; // push name, age+1 values
}
print_r($result);

PHP merge and reorder multidimensional array

I have 2 PHP arrays that look like this..
$array1
--------
Array
(
[0] => Array
(
[0] => 64
[1] => Apple
)
[1] => Array
(
[0] => 22
[1] => Pear
)
[2] => Array
(
[0] => 3
[1] => Raisin
)
[3] => Array
(
[0] => 15
[1] => Grape
)
[4] => Array
(
[0] => 11
[1] => Banana
)
[5] => Array
(
[0] => 4
[1] => Orange
)
)
$array2
--------
Array
(
[0] => Array
(
[0] => 22
[1] => Pear
)
[1] => Array
(
[0] => 11
[1] => Banana
)
)
I want to merge the arrays together but put the matching items from $array2 at the top so the result would look like this...
$array3
-------
Array
(
[0] => Array
(
[0] => 22
[1] => Pear
)
[1] => Array
(
[0] => 11
[1] => Banana
)
[2] => Array
(
[0] => 64
[1] => Apple
)
[3] => Array
(
[0] => 3
[1] => Raisin
)
[4] => Array
(
[0] => 15
[1] => Grape
)
[5] => Array
(
[0] => 4
[1] => Orange
)
)
I'm not sure how to approach, should I merge the two first and then try and do some ordering, or is there a more efficient approach?
Get the 2nd array and then a rest of the 1st array
array_merge($arr2, array_udiff($arr1, $arr2, function($i1, $i2) {return $i1[0]-$i2[0];}));

PHP Array Distinct element breakup

I dynamically pulling results from a database and putting them in an array $myArray, which looks like below
Array (
[0] => Array (
[0] => Array (
[Fruit] => Apple
[Number] => 1
[Date] => 3117-01-41
[supplier] => Store 1
[description] => SAmple text for apple )
[1] => Array (
[Fruit] => Orange
[Number] => 1932
[Date] => 3117-01-41
[supplier] => Store 2
[description] => Sample text for Orange )
[2] => Array (
[Fruit] => Grape
[Number] => 22
[Date] => 3117-01-41
[supplier] => Store Street
[description] => Sample Text for Grape )
[3] => Array (
[Fruit] => Apple
[Number] => 23
[Date] => 3117-01-41
[supplier] => Store 9
[description] => This is text for a second apple )
[4] => Array (
[Fruit] => Apple
[Number] => 49
[Date] => 3117-01-41
[supplier] => Store 007
[description] => This is more text for some apples )
[5] => Array (
[Fruit] => Orange
[Number] => 1
[Date] => 3117-01-41
[supplier] => Store 7
[description] => This is for orange also )
)
)
The ideal would be to create a new array so the original stays untouched
$newArray = $myArray;
What i want to do is in the new array select a distinct field for example 'Fruit' it would display a distinct fruit but if other fields are different make a nested array within the new array for.
<!-- Desired output of $newArray -->
[0] => Array (
[Fruit] => Apple
[Number] => Array
(
[0] => 1
[1] => 23
[2] => 49
)
[Date] => Array
(
[0] => 3117-01-41
[1] => 3117-01-41
[2] => 3117-01-41
)
[supplier] => Array
(
[0] => Store 1
[1] => Store 9
[2] => Store 007
)
[description] => Array
(
[0] => SAmple text for apple
[1] => This is text for a second apple
[2] => This is more text for some apples
) )
[1] => Array (
[Fruit] => Orange
[Number] => Array
(
[0] => 1932
[1] => 1
)
[Date] => Array
(
[0] => 3117-01-41
[1] => 3117-01-41
[2] => 3117-01-41
)
[supplier] => Array
(
[0] => Store 2
[1] => Store 7
)
[description] => Array
(
[0] => Sample text for Orange
[1] => This is for orange also
) )
<!--Grape contents-->
First combine the array of same fruit. Now you will have same multiple fruits array under single array. Then just iterate that array & format the response.
$tempArray = [];
//creates the array of common fruit
foreach ($myArray[0] as $key => $value) {
$tempArray[$value['Fruit']][] = $value;
}
$newarray = [];
//iterate the new array of array of fruits
foreach ($tempArray as $key => $value) {
//here value will be common fruit array so iterate & format the array
$temp = [];
$temp['Fruit'] = $value[0]['Fruit'];
foreach ($value as $key => $val) {
$temp['Number'][] = $val['Number'];
$temp['Date'][] = $val['Date'];
$temp['supplier'][] = $val['supplier'];
$temp['description'][] = $val['description'];
}
$newarray [] = $temp;
}
var_dump($newarray);

PHP Merge array with same keys and one same value

I need to merge a PHP array, this array has 2 arrays into it named "targetXX", I can have 2 or more. Each target have the same keys, for each key I have an array with 2 values a and b, a is always the same in both targets, but I need to merge both B values like this:
Array
(
[0] => Array
(
[target] => hitcount(stats.asdf1.requests, "1min")
[datapoints] => Array
(
[0] => Array
(
[0] => 1200
[1] => 1392282200
)
[1] => Array
(
[0] => 1400
[1] => 1392282260
)
[2] => Array
(
[0] => 600
[1] => 1392282320
)
[3] => Array
(
[0] => 200
[1] => 1392282380
)
[4] => Array
(
[0] => 400
[1] => 1392282440
)
[5] => Array
(
[0] => 600
[1] => 1392282500
)
)
)
[1] => Array
(
[target] => hitcount(stats.asdf.requests, "1min")
[datapoints] => Array
(
[0] => Array
(
[0] => 4321
[1] => 1392282200
)
[1] => Array
(
[0] => 76567
[1] => 1392282260
)
[2] => Array
(
[0] => 5556
[1] => 1392282320
)
[3] => Array
(
[0] => 7675
[1] => 1392282380
)
[4] => Array
(
[0] => 2344
[1] => 1392282440
)
[5] => Array
(
[0] => 0999
[1] => 1392282500
)
)
)
Result:
Array
(
[0] => Array
(
[target] => hitcount(stats.asdf1.requests, "1min")
[datapoints] => Array
(
[0] => Array
(
[0] => 1200
[1] => 1392282200
[2] => 4321
)
[1] => Array
(
[0] => 1400
[1] => 1392282260
[2] => 76567
)
[2] => Array
(
[0] => 600
[1] => 1392282320
[2] => 5556
)
[3] => Array
(
[0] => 200
[1] => 1392282380
[2] => 7675
)
[4] => Array
(
[0] => 400
[1] => 1392282440
[2] => 2344
)
[5] => Array
(
[0] => 600
[1] => 1392282500
[2] => 0999
)
)
)
Use array_merge() to achieve this:
$newArray = array();
foreach ($myArray['target2'] as $key => $innerArr1) {
$newArray['target'][$key] = array_merge(
$myArray['target1'][$key], /* 0th and 1st index */
array($innerArr1[1]) /* 2nd index */
);
}
print_r($newArray);
Output:
Array
(
[target] => Array
(
[0] => Array
(
[0] => 333333
[1] => 13
[2] => 99
)
[1] => Array
(
[0] => 444444
[1] => 15
[2] => 98
)
[2] => Array
(
[0] => 555555
[1] => 17
[2] => 97
)
)
)
Demo
The built-in function array_merge may do the work for you. You need to merge each subarrays in fact, as the array_merge_recursive function doesn't handle indexes.
$newArray = array();
foreach ($myArray['target2'] as $key => $arr) {
$newArray['target'][$key] = array_merge($myArray['target1'][$key], $arr[1]);
}
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
If you have more than 2 keys to merge, you can loop on the algorithm multiple times.

Output arrays within an array grouped by a common index

I have an array, seen below. My desired output is to group by store, and then concatenate (I think?) all of the related quantities and denominations into those arrays. I've shown what the desired output would be.
CURRENT ARRAY
Array
(
[denomination] => Array
(
[0] => 25
[1] => 50
[2] => 100
[3] => 200
)
[quantity] => Array
(
[0] => 1
[1] => 1
[2] => 2
[3] => 4
)
[store] => Array
(
[0] => candy store
[1] => candy store
[2] => book store
[3] => candy store
)
)
DESIRED OUTPUT
Array
(
[candy store] => Array
(
[0] => Array
(
[denomination] => Array
(
[0] => 25
[1] => 50
[2] => 200
)
)
[1] => Array
(
[quantity] => Array
(
[0] => 1
[1] => 1
[2] => 4
)
)
)
[book store] => Array
(
[0] => Array
(
[denomination] => Array
(
[0] => 100
)
)
[1] => Array
(
[quantity] => Array
(
[0] => 2
)
)
)
)
$result = array();
foreach ($array['store'] as $index => $type) {
$result[$type]['denomination'][] = $array['demoniation'][$index];
$result[$type]['quantity'][] = $array['quantity'][$index];
}
This is not exactly, what you specified as "desired output", but I don't see a reason, why one should put the denomination- and quantity-arrays into additional arrays.
However, if this has any reason, you can get it similar
$result = array();
foreach ($array['store'] as $index => $type) {
$result[$type][0]['denomination'][] = $array['demoniation'][$index];
$result[$type][1]['quantity'][] = $array['quantity'][$index];
}

Categories