Adam Pietrasiak
Adam Pietrasiak

Reputation: 13224

PHP merge array on nulls

I have 2 * array and I want to merge them, but each of theme have some NULL rows.

$a = array(
    'a' => NULL,
    'b' => 1,
    'c' => 1
);

$b = array(
    'a' => 1,
    'b' => NULL,
    'c' => 1    
);

So, code:

$c = array_merge($a,$b);

Will give $c:

array {
  'a'=> 1
  'b'=> NULL
  'c'=>1
}

Is there build in or simple way to do margin ($a,$b) like following, but now $a is overwritten for every same index from $b. I want $b to be overwritten by $a index if $b index is null - in example $b['b'] should be overwritten from $a

All NULL rows should be filled if possible.

Upvotes: 11

Views: 17430

Answers (5)

jbmilgrom
jbmilgrom

Reputation: 23251

None of these answers address merging two arrays that may have different keys, which is what lead me to this SO post. It happens to actually be pretty straight forward fortunately:

function arrayMergeIfNotNull($arr1, $arr2) {
    foreach($arr2 as $key => $val) {
        $is_set_and_not_null = isset($arr1[$key]);
        if ( $val == NULL && $is_set_and_not_null ) {
            $arr2[$key] = $arr1[$key];
        }
    }
    return array_merge($arr1, $arr2);
}

Now, merging these two arrays:

$a = array('a' => NULL, 'b' => 1, 'c' => 1, 'd' => NULL, 'z' => 'zebra');
$b = array('a' => 1, 'b' => NULL, 'c' => 1, 'd' => NULL, 'f' => 'frank');

with:

var_dump(arrayMergeIfNotNull($a, $b));

will produce:

array (size=6)
  'a' => int 1
  'b' => int 1
  'c' => int 1
  'd' => NULL
  'z' => 'zebra'
  'f' => 'frank'

Note this answer also solves the problem of two arrays with the same keys.

Upvotes: 2

You Old Fool
You Old Fool

Reputation: 22950

I would do it with a simple one liner like this:

$c = array_filter($b) + array_filter($a) + array_fill_keys(array_keys($b),null);

This would preserve all keys and values of $b except where falsey in which case they will be either replaced with values from $a or as a last resort replaced with null.

When merging arrays with the + operator the order in which they appear from left to right equates to the precedence. So the leftmost position will hold it's value unless the key does not exist.

You can also reverse the order and use array_merge(), but for me it's harder on the eyes:

$c = array_merge(array_fill_keys(array_keys($b),null) + array_filter($a) + array_filter($b));

Upvotes: 3

Fabio
Fabio

Reputation: 23510

I think you can use array_filter function to remove null values in both array and then merge them

$a = array(
    'a' => NULL,
    'b' => 1,
    'c' => 1
);

$b = array(
    'a' => 1,
    'b' => NULL,
    'c' => 1    
);

$b  = array_filter($b);
$a  = array_filter($a);
$c = array_merge($a, $b);
var_dump($c);

This will output

array(3) {
  ["b"]=> int(1)
  ["c"]=> int(1)
  ["a"]=> int(1)
}

LIVE SAMPLE

As side note i would add that using array_filter without second parameter will end up in deleting all NULL values as well as EMPTY array etc. If you want to only remove NULL values so you will need to use array_filter($yourarray, 'strlen');

EDITED

If you want to preserve NULL if both arrays have it with the same key and supposing that both arrays have same number of keys/values, then you will need to loop inside your array and build a new array preserving NULL where you need

$a = array(
    'a' => NULL,
    'b' => 1,
    'c' => 1,
    'd' => NULL
);

$b = array(
    'a' => 1,
    'b' => NULL,
    'c' => 1,   
    'd' => NULL,
);

$c = array();
foreach($a as $key => $val)
{
    if($key == NULL && $b[$key] == NULL)
    {
        $c[$key] = $val;
    } else if($key != NULL && $b[$key] == NULL) {
        $c[$key]= $val;
    } else if($key != NULL && $b[$key] != NULL) {
        $c[$key]= $b[$key];
    } else {
        $c[$key]= $b[$key];
    }
}
var_dump($c);

This will output

array (size=4)
  'a' => int 1
  'b' => int 1
  'c' => int 1
  'd' => NULL

LIVE SAMPLE

Upvotes: 21

gkalpak
gkalpak

Reputation: 48211

If you need to preserve keys that have a value of NULL in both arrays, you can use a custom function that ignores those entries from the second array if (and only if) there is a corresponding non-NULL entry in the first array. It would look like this:

function arrayMergeIgnoringNull($arr1, $arr2) {
    $new2 = array();
    forEach ($arr2 as $key => $value) {
        if (($value !== NULL) || !isSet($arr1[$key])) {
           $new2[$key] = $value;
        } 
    }
    return array_merge($arr1, $new2);
}
$c = arrayMergeIgnoringNull($a, $b);

See, also, this short demo.

Upvotes: 0

MjeOsX
MjeOsX

Reputation: 405

then you have to pass $b as the first parameter

$c = array_merge($b,$a);

you can use this function

function mergeArray($array1, $array2)
{
    $result = array();

    foreach ($array1 as $key=>$value)
    {
        $result[$key] = $value;
    }

    foreach ($array2 as $key=>$value)
    {
        if (!isset($result[$key] || $result[$key] == null)
        {
            $result[$key] = $value;
        }
    }

    return $result;
}

Upvotes: 0

Related Questions