Imrickjames
Imrickjames

Reputation: 129

Merge 2 arrays with null values

I want to merge 2 tables I show you an example:

foreach ($dashboardData as $item) {
    $results[$item['month']] = [
        DashboardConsts::COLUMN_MONTHLY => $item['month'] ?? null,
        DashboardConsts::ROW_NBR => $item['nbr'] ?? null,
        DashboardConsts::ROW_SELL_PRICE => $item['sum'] ?? null,
        'number' => $item['countNewBc'] ?? null,
    ];
}

array:2 [▼
  "2020-12" => array:4 [▼
    "Mois" => "2020-12"
    "Nbr vendus" => null
    "CA TTC" => null
    "number" => "1"
  ]
  "2021-01" => array:4 [▼
    "Mois" => "2021-01"
    "Nbr vendus" => null
    "CA TTC" => null
    "number" => "2"
  ]
]

and

"2020-12" => array:4 [▼
  "Mois" => "2020-12"
  "Nbr vendus" => "1"
  "CA TTC" => "790"
  "number" => null
]
"2021-01" => array:4 [▼
  "Mois" => "2021-01"
  "Nbr vendus" => "3"
  "CA TTC" => "1680"
  "number" => null
]

Basically here, I make a sort of group my values ​​by period, I try to merge my 2 arrays to ensure that the fields which are 'null'.

I want to replace null values ​​with those that are filled in one of the array.

I had to try to do something like that :

$tableau1  = array_filter($tableau1);
$tableau2  = array_filter($tableau2);
$result = array_merge($tableau1, $tableau2);

but it does not work.

EDIT:

I wish my final result looks like this

array:2 [▼
  "2020-12" => array:4 [▼
    "Mois" => "2020-12"
    "Nbr vendus" => "1"
    "CA TTC" => "790"
    "number" => "1"
  ]
  "2021-01" => array:4 [▼
    "Mois" => "2021-01"
    "Nbr vendus" => "3"
    "CA TTC" => "1680"
    "number" => "2"
  ]
]

Upvotes: 1

Views: 770

Answers (3)

bestprogrammerintheworld
bestprogrammerintheworld

Reputation: 5520

I know you got your answer, but if someone stumbles upon this question and don't need recursive (only one level down in array) check then you could do this: (My logic is simply to replace null with zeros and add together equivalent keys from the arrays. In my code I also take for granted that there are same the same keys in inner array for each array)

$new_arr = array_slice($array1,0);
foreach($array1 as $headkey=>$item) {
    foreach($item as $innerkey=>$it) {
        $null_change = false;
        if ($array1[$headkey][$innerkey] === null) {
            $array1[$headkey][$innerkey] == 0;
            $null_change = true;
        }
        if ($array2[$headkey][$innerkey] === null) {
            $array2[$headkey][$innerkey] == 0;
            $null_change = true;
        }
        
        if ($null_change === true) {
            $new_arr[$headkey][$innerkey] = $array1[$headkey][$innerkey] + 
            $array2[$headkey][$innerkey];
        } 
    }
}
var_dump($new_arr);

If you need a more generic result based on unknown number of arrays you could do this (but still only one level in each array):

function replaceNullOccurences(...$arrays) {
    if (!is_array($arrays[0])) return;
    $new_arr = array_slice($arrays[0],0);
    foreach($arrays[0] as $headkey=>$item) {
        foreach($item as $innerkey=>$it) {
            $null_change = false;
            foreach($arrays as $arr) {
                if ($arr[$headkey][$innerkey] === null) {
                    $arr[$headkey][$innerkey] == 0; //Change null to zero for addition below
                    $null_change = true;
                }
            }
            //If null in the key in any array, sum together the arrays
            if ($null_change === true) {
                foreach($arrays as $arr) {            
                    $new_arr[$headkey][$innerkey] += $arr[$headkey][$innerkey];
                }
            }
        }
    }
    return $new_arr;        
}

$result = replaceNullOccurences($array1, $array2);

Upvotes: 1

Anuga
Anuga

Reputation: 2827

There are many ways of achieving this, all the solutions, needs to go through the arrays, one way or another.

You easily do a foreach () loop marathon and and loads of if () statements to make sure the conversion is correctly made.

Anyways, this is my take on the question.

Remove null values and replace them with array_replace_recursive():

<?php

function array_remove_null($input) { 
  foreach ($input as &$value) { 
    if (is_array($value)) { 
      $value = array_remove_null($value); 
    }
  }
  return array_filter($input, function($item){
    return $item !== null && $item !== '';
  }); 
}

/**
 * Using https://www.php.net/manual/en/function.array-replace-recursive.php
 */

$array1 = [
    "2020-12" => [
        "Mois" => "2020-12",
        "Nbr vendus" => null,
        "CA TTC" => null,
        "number" => "1",
    ],
    "2021-01" => [
        "Mois" => "2021-01",
        "Nbr vendus" => null,
        "CA TTC" => null,
        "number" => "2",
    ],
];

$array2 = [
    "2020-12" => [
        "Mois" => "2020-12",
        "Nbr vendus" => "1",
        "CA TTC" => "790",
        "number" => null,
    ],
    "2021-01" => [
        "Mois" => "2021-01",
        "Nbr vendus" => "3",
        "CA TTC" => "1680",
        "number" => null,
    ],
];

$array = array_replace_recursive(array_remove_null($array1), array_remove_null($array2));

var_dump($array);

In action: https://3v4l.org/WJnYu

Upvotes: 3

Millar248
Millar248

Reputation: 401

I think I understand. You need a nested loop to access both sets of data. The following might not be the actual answer, but it's close.

$results = array();
foreach ($inputArrayOne as $onekey => $arrayOne) {
    $temp_results = array();
    foreach ($inputArrayTwo as $twokey => $arrayTwo) {
        if ($onekey != $twokey) {
            continue;
        }
        if (!is_null($arrayOne['month'])) {
            $temp_results['Mois'] = $arrayOne['month'];
        } else if (!is_null($arrayTwo['month'])) {
            $temp_results['Mois'] = $arrayTwo['month'];
        } else {
            $temp_results['Mois'] = null;   // to account for bad data
        }
        if (!is_null($arrayOne['nbr'])) {
            $temp_results['Nbr vendus'] = $arrayOne['nbr'];
        } else if (!is_null($arrayTwo['nbr'])) {
            $temp_results['Nbr vendus'] = $arrayTwo['nbr'];
        } else {
            $temp_results['Nbr vendus'] = null; // to account for bad data
        }
        if (!is_null($arrayOne['sum'])) {
            $temp_results['CA TTC'] = $arrayOne['sum'];
        } else if (!is_null($arrayTwo['sum'])) {
            $temp_results['CA TTC'] = $arrayTwo['sum'];
        } else {
            $temp_results['CA TTC'] = null; // to account for bad data
        }
        if (!is_null($arrayOne['countNewBc'])) {
            $temp_results['number'] = $arrayOne['countNewBc'];
        } else if (!is_null($arrayTwo['countNewBc'])) {
            $temp_results['number'] = $arrayTwo['countNewBc'];
        } else {
            $temp_results['number'] = null; // to account for bad data
        }
    }
    $results[$arrayOne['month']] = $temp_results;
}

Upvotes: 1

Related Questions