MichaelP
MichaelP

Reputation: 181

Get the associative differences between two associative arrays

I have 2 arrays that I want to compare. On side A, it contains IPtables rules split up in separate columns. Example output array A;

Array
(
    [0] => Array
        (
            [num] => 1
            [pkts] => 0
            [bytes] => 0
            [target] => DROP
            [prot] => all
            [opt] => --
            [in] => *
            [out] => *
            [source] => 192.168.0.1/32
            [destination] => 192.168.0.2/32

        )

On side B, I also have an array. However, this one has a slight difference.

   [1] => Array
        (
            [num] => 2
            [pkts] => 0
            [bytes] => 0
            [target] => DROP
            [prot] => all
            [opt] => --
            [in] => *
            [out] => *
            [source] => 192.168.5.5/32
            [destination] => 192.168.6.6/32
            [id] => 7
        )

As you can see, Array B has another column. Column ID.

What I want to do is, compare these two from the eyes of A.

So,

A-->B then I want to output the difference.

In the field I have array A filled with 3 rules, and Array B for example 4 rules.

Array A needs to look at Array B, then output what is not in there.

Array B needs to be a exact copy of Array A, so to speak.

What I've tried, is to use array_diff. However, I've found out that that doesn't work since there's an ID column in array B, always being the difference.

So essentially what I'm looking for is a modified array_diff that doesn't look at the ID column in Array B... how to achieve this?

Upvotes: 0

Views: 106

Answers (3)

Marcel
Marcel

Reputation: 5119

So where 's the problem?

$arr1 = new ArrayObject(array('a' => 'bla', 'b' => 'blubb'));
$arr2 = new ArrayObject(array('a' => 'bla', 'b' => 'blubb', 'id' => 7));
$ignore = new ArrayObject(array('id'));

function compare(ArrayObject $arr1, ArrayObject $arr2, ArrayObject $ignore = null) {
    if ($ignore !== null && $ignore->count()) {
        foreach ($ignore as $offset2Ignore) {
            if ($arr2->offsetExists($offset2Ignore)) {
                $arr2->offsetUnset($offset2Ignore);
            }
        }
    }
    return $arr1 == $arr2;
}

What does the code shown above= First it uses the SPL ArrayObject instead of a simple array. Second we define the offsets, which have to be ignored in the second array. If we have to ignore an offset, wie iterate through the ignore items and unset the offset. After that wie compare the to arrays. If they are equal the funktion returns true ... otherwise false.

If you want to know the differences between to arrays, you can change the return value at the code above by using array_diff().

Upvotes: 2

Minoru
Minoru

Reputation: 1730

Another possibility for what Michael Helwig did is to do the opposite.

Add an id field in the side A array an use the array_diff_uassoc function. If you need, just unset the added id field later.

Upvotes: 1

Michael Helwig
Michael Helwig

Reputation: 530

As already mentioned, you could either unset the id from the inner array via unset or write your own comparison function via array_diff_uassoc:

http://www.php.net/manual/en/function.array-diff-uassoc.php

Upvotes: 2

Related Questions