phparraysmultidimensional-arrayfilterarray-difference

Find row differences between two 2d arrays


Finishing up an open source Domain Registrar plugin and having a few troubles with determining when a change has been made.

$saved = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '8.8.8.8' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' )
    );

$new = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' ),
        array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
    );

$saved is the values already saved at the domain registrar, and is only being used for comparison.

$new is the array returned from application that processed the form on the website.

I need to somehow only return arrays that have values that were updated or that do not already exist/match from $saved.

Basically the return array i'm looking for would be:

array(
    array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' )
    array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
);

Because in $saved the value was updated from 8.8.8.8 to 4.4.4.4, and the sub.mydomain.com did not match any array from $saved meaning it's a new entry.

Using array_intersect I was able to get it to return the array that had it's values updated, but unfortunately it still includes the arrays that matched as well. If I could somehow have those removed that would be exactly what I need.

Here's a demo: http://glot.io/php/529b0c6d2fd16fe221f86bb521155384

Maybe use array_uintersect with a callback to check if the arrays match and unset?


Solution

  • Well in this case you could flatten them thru serializing, them map, them finally array_dif()

    $result = array_map('unserialize', array_diff(array_map('serialize', $new), array_map('serialize', $saved)));
    

    Should produce based on example:

    Array
    (
        [0] => Array
            (
                [domain] => mydomain.com
                [record] => A
                [value] => 4.4.4.4
            )
    
        [2] => Array
            (
                [domain] => sub.mydomain.com
                [record] => A
                [value] => 1.2.3.4
            )
    
    )