Reputation: 4180
So, I have three arrays:
$foo
Array
(
[0] => Array
(
[sum] => 281
[status] => 0
)
[1] => Array
(
[sum] => 1534
[status] => 1
)
[2] => Array
(
[sum] => 1434
[status] => 2
)
[3] => Array
(
[sum] => 2468
[status] => 3
)
)
$rock
Array
(
[0] => Array
(
[sum] => 514
[status] => 0
)
[1] => Array
(
[sum] => 500
[status] => 1
)
)
$bar
Array
(
[0] => Array
(
[sum] => 458
[status] => 0
)
[1] => Array
(
[sum] => 500
[status] => 1
)
)
I need to merge $bar
and $rock
with $foo
, such that the key sum is added.
for example:
on merging $bar
and $rock
with $foo
, the first index, where status
is 0 would look something like this:
[0] => Array
(
[sum] => 1253 (281 + 514 + 458)
[status] => 0
)
And the merge should happen based on the status
. status
0 from $rock
would merge to status
0 of $foo
I was thinking if this is a recursion application and making things more complex.
How should I solve it in an easy and optimized manner?
Upvotes: 0
Views: 64
Reputation: 12376
I am always a fan of general use functions that could be used in the future. This solution takes three arguments:
1) An array of all the arrays that need to be combined
2) The key which will be used as a basis of comparison (two nodes that have the key will be combined)
3) The data-key which will be the field that is combined if the nodes are 'equal'
Lastly, php is very good at making dictionaries/hashmaps. This will help when we combine arrays because we won't have to do much searching.
/**
* $arrays - an array of arrays to be combined
* $key - a key in the array that represents the key that holds the values that need to be compared
* $data - a key in the array that represens the key that holds the data
*/
function combine($arrays, $key, $data) {
$ans = array();
//Go through each array that needs to be combined
foreach($arrays as $nodes) {
//go through each node of the array
foreach($nodes as $node) {
//make sure the node actually has the key we need
if (isset($node[$key])) {
//initialize the answer to a new node(array with key, data)
$ansKey = $node[$key];
if (!isset($ans[$node[$key]])) {
$ans[$ansKey] = array();
$ans[$ansKey][$key] = $node[$key];
$ans[$ansKey][$data] = 0;
}
//make sure the node actually has the data we need
if (isset($node[$data])) {
//combined the data
$ans[$ansKey][$data] += $node[$data];
}
}
}
}
//we only care about the nodes, not the ansKeys we used to get there
return array_values($ans);
}
In your example you would call combine(array($rock, $foo, $bar), "status", "sum")
This function should be O(n)
where n
is the number of nodes. Each node is processed exactly once and because php arrays have a lookup of O(1) we lose no time searching for previous values because all lookups are done on array indexes and not array values.
When I ran the function with your data it returned -
Array
(
[0] => Array
(
[status] => 0
[sum] => 1253
)
[1] => Array
(
[status] => 1
[sum] => 2534
)
[2] => Array
(
[status] => 2
[sum] => 1434
)
[3] => Array
(
[status] => 3
[sum] => 2468
)
)
Upvotes: 1