Difference between two Multidimensional Arrays with PHP

3

I have these two multidimensional arrays and would like the difference between them, similar to what the array_diff function does, but with multidimensional arrays:

$array_1:

Array
(
    [0] => Array
        (
            [idAmbiente] => 1
            [nomeAmbiente] => Desenvolvimento
            [codAmbiente] => D
        )

    [1] => Array
        (
            [idAmbiente] => 2
            [nomeAmbiente] => Produção
            [codAmbiente] => P
        )

    [2] => Array
        (
            [idAmbiente] => 3
            [nomeAmbiente] => Testes
            [codAmbiente] => T
        ) 
)

$array_2:

Array
(
    [0] => Array
        (
            [idVisibilidade] => 14
            [urlSistema] => http://www-gexdia/prevsuporte
            [responsavelVisibilidade] => 12
            [sistema_idSistema] => 10
            [idAmbiente] => 2
            [dataBaseList] => 18
        ) 
)

I would like the function to do something like: array_diff_multidimensional($array_1,$array_2,'idAmbiente');

Result:

Array
( 
    [0] => Array
        (
            [idAmbiente] => 1
            [nomeAmbiente] => Desenvolvimento
            [codAmbiente] => D
        )

    [1] => Array
        (
            [idAmbiente] => 3
            [nomeAmbiente] => Testes
            [codAmbiente] => T
        ) 
)
    
asked by anonymous 19.07.2014 / 23:28

2 answers

4

I made two functions, array_enkeyize to transform the value of an item into key of the arrays and array_dekeyize to transform the key into a value of an item declared in the parameters

function array_enkeyize($array, $iten) {
  foreach ($array as $key => $value) {
    foreach ($value as $v_key => $v_value) {
        if ($v_key === $iten){
            $keized[$v_value] = $array[$key];
            unset($keized[$v_value][$iten]);
        }     
    }
  }

  return $keized;
}


function array_dekeyize($array, $iten) {
    $i = 0;
  foreach ($array as $key => $value) {      
    $dekeized[$i] = $array[$key];
    $dekeized[$i++][$iten] = $key; 
  }

  return $dekeized;
}

How to use

$array1 = array_enkeyize($array_1, 'idAmbiente');
$array2 = array_enkeyize($array_2, 'idAmbiente');

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

$result = array_dekeyize($result, 'idAmbiente');

var_dump($result);

Result

array (size=2)
  0 => 
    array (size=3)
      'nomeAmbiente' => string 'Desenvolvimento' (length=15)
      'codAmbiente' => string 'D' (length=1)
      'idAmbiente' => int 1
  1 => 
    array (size=3)
      'nomeAmbiente' => string 'Testes' (length=6)
      'codAmbiente' => string 'T' (length=1)
      'idAmbiente' => int 3

=)

    
22.07.2014 / 17:01
2

Since the key is relevant for the comparison between the arrays (idAmbiente), what you are looking for is something closer to a array_diff_assoc

Because your arrays are multidimensional, you will need a recursive function to traverse and compare the internal arrays. In the comments of the php documentation itself we have the implementation of the recursive function you need :

<?php
function array_diff_assoc_recursive($array1, $array2)
{
    foreach($array1 as $key => $value)
    {
        if(is_array($value))
        {
              if(!isset($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              elseif(!is_array($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              else
              {
                  $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                  if($new_diff != FALSE)
                  {
                        $difference[$key] = $new_diff;
                  }
              }
          }
          elseif(!isset($array2[$key]) || $array2[$key] != $value)
          {
              $difference[$key] = $value;
          }
    }
    return !isset($difference) ? 0 : $difference;
} 

Since this function uses isset , if your array has a key with null , the result may not be as expected because isset will return the position in null even if they match between arrays:

<?php

$array1 = array('a' => null, 'b' => null);
$array2 = array('a' => null);

var_dump(array_diff_assoc_recursive($array1, $array2));

Return:

array(1) {
  [0]=>
  array(2) {
    ["a"]=>
    NULL
    ["b"]=>
    NULL
  }
}

To circumvent this situation, in the comments of the same function, we have a implementation that replaces o isset by array_key_exists .

I recommend using the implementation with array_key_exists only if you really of the difference between null keys. Recursive functions are slower by nature , and since isset is faster than array_key_exists because it is a language constructor and not a function, in cases of giant arrays isset will perform better .

    
19.07.2014 / 23:48