IkouKuhn
IkouKuhn

Reputation: 89

Merge multi-dimensional arrays by relating first columns and summing two other columns

I want to combine two multidimensional arrays in PHP.

print_r($array_a):

Array
(
[0] => Array
    (
        [0] => A
        [1] => 0
        [2] => 1047
    )

[1] => Array
    (
        [0] => B
        [1] => 0
        [2] => 279
    )

[2] => Array
    (
        [0] => C
        [1] => 0
        [2] => 68
    )

[3] => Array
    (
        [0] => D
        [1] => 0
        [2] => 4
    )

)

print_r($array_b):

Array
(
[0] => Array
    (
        [0] => A
        [1] => 76
        [2] => 0
    )

[1] => Array
    (
        [0] => B
        [1] => 170
        [2] => 0
    )

[2] => Array
    (
        [0] => C
        [1] => 15
        [2] => 0
    )

[3] => Array
    (
        [0] => D
        [1] => 210
        [2] => 0
    )
[4] => Array
    (
        [0] => E
        [1] => 287
        [2] => 0
    )

)

Then merge it, the result should be like this:

Array
(
[0] => Array
    (
        [0] => A
        [1] => 76
        [2] => 1047
    )

[1] => Array
    (
        [0] => B
        [1] => 170
        [2] => 279
    )

[2] => Array
    (
        [0] => C
        [1] => 15
        [2] => 68
    )

[3] => Array
    (
        [0] => D
        [1] => 210
        [2] => 4
    )
[4] => Array
    (
        [0] => E
        [1] => 287
        [2] => 0
    )

)

So the logic key is to merge the two array based on the first value of each array(A, B, C, D). And if there's an array that belong only in one of the array (for example, "E" on the array_b), I just add them. I tried this:

foreach($array_a as $a=>$array_now){
        foreach($array_b as $b=>$array_before){
            if($array_now[0] == $array_before[0]){
                $array_a[$a] = [$array_before[0], $array_before[1], $array_now[2]];
            }
        }
    }

But I can't seem to add the missing array (the 5th array in $array_b which contain 'E').

Upvotes: 0

Views: 105

Answers (4)

mickmackusa
mickmackusa

Reputation: 47864

This task can be concisely, efficiently, and reliably performed with a single loop which generates a result array with temporary key to determine whether a new row is encountered or not.

Code: (Demo)

$array_a = [
  ['A', 0, 1047],
  ['B', 0, 279],
  ['C', 0, 68],
  ['D', 0, 4],
];

$array_b = [
  ['A', 76, 0],
  ['B', 170, 0],
  ['E', 287, 0],
  ['C', 15, 0],
  ['D', 210, 0],
];


foreach (array_merge($array_a, $array_b) as $row) {
    if (!isset($result[$row[0]])) {
        $result[$row[0]] = $row;
    } else {
        $result[$row[0]][1] += $row[1];
        $result[$row[0]][2] += $row[2];
    }
}
var_export(array_values($result));

Output:

array (
  0 => 
  array (
    0 => 'A',
    1 => 76,
    2 => 1047,
  ),
  1 => 
  array (
    0 => 'B',
    1 => 170,
    2 => 279,
  ),
  2 => 
  array (
    0 => 'C',
    1 => 15,
    2 => 68,
  ),
  3 => 
  array (
    0 => 'D',
    1 => 210,
    2 => 4,
  ),
  4 => 
  array (
    0 => 'E',
    1 => 287,
    2 => 0,
  ),
)

Upvotes: 0

IkouKuhn
IkouKuhn

Reputation: 89

Sorry but all the above solution doesn't work, and I figured it by myself, by using this code:

    $result = array();
    if (count($array_a) > count($array_b)){
        foreach($array_a as $a=>$array_now){
            foreach($array_b as $b=>$array_before){
                if($array_now[0] == $array_before[0]){
                    $array_a[$a] = [(string)$array_before[0], (int)$array_before[1], (int)$array_now[2]];
                }
            }
        }
        $result = $array_a;
    } else {
        foreach($array_b as $a=>$array_now){
            foreach($array_a as $b=>$array_before){
                if($array_now[0] == $array_before[0]){
                    $array_b[$a] = [(string)$array_before[0], (int)$array_now[1], (int)$array_before[2]];
                }
            }
        }
        $result = $array_b;
    }

Thank you guys for all of your response.

Upvotes: 0

Ashok Chandrapal
Ashok Chandrapal

Reputation: 1020

use below code that will help you

$array_a = [];
$array_a[0][0] = 'A';
$array_a[0][1] = 0;
$array_a[0][2] = 1047;

$array_a[1][0] = 'B';
$array_a[1][1] = 0;
$array_a[1][2] = 279;

$array_a[2][0] = 'C';
$array_a[2][1] = 0;
$array_a[2][2] = 68;

$array_a[3][0] = 'D';
$array_a[3][1] = 0;
$array_a[3][2] = 4;


$array_b = [];
$array_b[0][0] = 'A';
$array_b[0][1] = 76;
$array_b[0][2] = 0;

$array_b[1][0] = 'B';
$array_b[1][1] = 70;
$array_b[1][2] = 0;

$array_b[2][0] = 'C';
$array_b[2][1] = 15;
$array_b[2][2] = 0;

$array_b[3][0] = 'D';
$array_b[3][1] = 210;
$array_b[3][2] = 0;

$array_b[3][0] = 'E';
$array_b[3][1] = 287;
$array_b[3][2] = 0;

$array_b[4][0] = 'E';
$array_b[4][1] = 2870;
$array_b[4][2] = 0;


$cnt = 0;
if(count($array_b) > $array_a){
    $cnt =  count($array_b);
}else{
    $cnt =  count($array_a);
}


$array_new = [];
for($i=0; $i <= $cnt; $i++){
    $array_new[$i] = [];

    if(isset($array_a[$i][0])){
        $array_new[$i][0] = $array_a[$i][0];
    }else{
        $array_new[$i][0] = $array_b[$i][0];    
    }   

    if(isset($array_b[$i][1])){
        $array_new[$i][1] = $array_b[$i][1];
    }else{
        $array_new[$i][1] = 0;  
    }

    if(isset($array_a[$i][2])){
        $array_new[$i][2] = $array_a[$i][2];
    }else{
        $array_new[$i][2] = 0;  
    }


}

echo "<pre>";
print_r($array_new);

Hope this will help!

Upvotes: 1

Philipp
Philipp

Reputation: 15629

You could use multiple array_maps to achieve this

$c = array_map(function() {
    return array_map(function() {
        foreach (func_get_args() as $arg) {
            if ($arg) return $arg;
        }
        return func_get_arg(0);
    }, ...func_get_args());
}, $a, $b);

this code would also work with more than $a, $b - just add as much arrays as you want as param

Upvotes: 0

Related Questions