2个数组:只保留具有不同值的元素

I have 2 arrays:

Array
(
    [0] => Array
        (
            [id] => 1
            [fieldname] => banana
            [value] => yellow
        ) 
)

Array
(
    [0] => Array
        (
            [id] => 1
            [fieldname] => rome
            [value] => city
        )

    [1] => Array
        (
            [id] => 2
            [fieldname] => bla
            [value] => yes
        )
)

I want to create a new array that contains only elements where "id" is different. In other words I want to get this output:

Array
(
    [0] => Array
        (
            [id] => 2
            [fieldname] => bla
            [value] => yes
        )

)

[id] => 2 was the only different [id] so I keep it.

Said that I've already managed to achieve my goal with an inefficient pile of foreach, if statements and temp variables. I really don't want to use a wall of code for this very small thing so I started to look for a native PHP function with no success. What's the easiest way to get the result? Is it possible that I strictly need to use a foreach with so many if?

You can use array_udiff with a function.

Computes the difference of arrays by using a callback function for data comparison.

Returns an array containing all the values of the first array that are not present in any of the other arguments.


The code:

// Setup two arrays as per your question
$array1 = array (

  '0' => array (
    'id' => '1',
    'fieldname' => 'banana',
    'value' => 'yellow',
  )

);

$array2 = array (

  '0' => array (
    'id' => '1',
    'fieldname' => 'rome',
    'value' => 'city',
  ),

  '1' => array (
    'id' => '2',
    'fieldname' => 'bla',
    'value' => 'yes',
  )

);

// Setup the callback comparison function
function arrayCompare($array2, $array1) {
    return $array2['id'] - $array1['id'];
}

// Use array_udiff() with the two arrays and the callback function
$arrayDiff = array_udiff($array2, $array1, 'arrayCompare');
print_r($arrayDiff);

The above code returns the following:

Array (

  [1] => Array (
    [id] => 2
    [fieldname] => bla
    [value] => yes
  )

)

This should do it. Not super short and it does use a temporary variable, so perhaps not what you were looking for. I've named the two arrays one and two.

$ids = array();
$result = array();

foreach ($one as $x) {
    $ids[$x['id']] = 1; //This way, isset($x['id']) vill return true
}

foreach ($two as $x) {
    if (!isset($ids[$x['id']])) {
        $result[] = $x;
    }
}

I would be surprised if there wasn't an even more compact way to do it.

EDIT: This is an alternative variant with nested for each. Not particularly short either.

$result = array();

foreach ($one as $x) {
    foreach ($two as $y) {
        if ($x['id'] == $y['id']) {
            //A match, lets try the next $x
            continue 2;
        }
    }
    //No matching id in $two
    $result[] = $x;
}