nirvair
nirvair

Reputation: 4180

merging three arrays in php

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

Answers (1)

Scott
Scott

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

Related Questions