tags:

views:

1111

answers:

4

Is there a built-in function for PHP for me to check whether two arrays contain the same values ( order not important?).

For example, I want a function that returns me true for the following two inputs:

array('4','5','2') 
array('2','4','5')

Edit: I could have sorted the two arrays and compare them, but as I am such a lazy guy, I would still prefer a one-liner that I can pull out and use.

+2  A: 

The best solution is to sort both array and then compare them:

$a = array('4','5','2');
$b = array('2','4','5');
sort($a);
sort($b);
var_dump($a === $b);

As a function:

function array_equal($a, $b, $strict=false) {
    if (count($a) !== count($b)) {
        return false;
    }
    sort($a);
    sort($b);
    return ($strict && $a === $b) || $a == $b;
}

Here’s another algorithm looking for each element of A if it’s in B:

function array_equal($a, $b, $strict=false) {
    if (count($a) !== count($b)) {
        return false;
    }
    foreach ($a as $val) {
        $key = array_search($val, $b, $strict);
        if ($key === false) {
            return false;
        }
        unset($b[$key]);
    }
    return true;
}

But that has a complexity of O(n^2). So you better use the sorting method.

Gumbo
as I am such a lazy guy, I would still prefer a one-liner that I can pull out and use.
Ngu Soon Hui
@Ngu Soon Hui - so wrap Gumbo's code into a function (array_equals($arr1,$arr2))?
karim79
It would be helpful if the down-voter commented on why he voted my answer down.
Gumbo
+3  A: 

You can use array_diff.

$a = array('4','5','2');
$b = array('2','4','5');

if(count(array_diff($a, $b)) == 0) {
  // arrays contain the same elements
} else {
  // arrays contain different elements
}

However, a problem with this approach is that arrays can contain duplicate elements, and still match.

Kazar
Anyone know the details on performance difference between a diff and a sort in php?
Kazar
`if (array_diff($a, $b)) {}` would do. empty array evaluate to false.
SilentGhost
Using `array_diff` is easy. But it requires extra space (O(*n*)) as an additional array is created where those elements of *A* are stored, that are not also element of *B*.
Gumbo
@Gumbo: and is there a reason to care?
SilentGhost
@SilentGhost: Not if you have infinite time and space. But who has that?
Gumbo
+5  A: 

array_diff looks like an option:

function array_equal($a1, $a2) {
  return !array_diff($a1, $a2);
}

or as an oneliner in your code:

if(!array_diff($a1, $a2)) doSomething();
knittl
You can use `empty` only with varliables.
Gumbo
gumbo: no, you can use it on arrays just fine. taken from <http://php.net/empty>: “The following things are considered to be empty: # array() (an empty array)”
knittl
Gumbo is right. You can't use a function's return value with `empty`. That's what he was actually saying. You have to store the return value of `array_diff` in a temp variable or just use the not operator: `return !array_diff($a1, $a2)`.
Ionuț G. Stan
@knittl: No, you can only test variables and not values. *`empty()` only checks variables as anything else will result in a parse error.* Again, see http://docs.php.net/empty
Gumbo
ionut: ok, that makes more sense. i’ve just tried it, and you’re both correct. i edited my answer to use a boolean cast (negate)
knittl
A parse error or a `Fatal error: Can't use function return value in write context`. In knittl's case the fatal error will be issued.
Ionuț G. Stan
A: 

The array_diff() method above won't work.

php.net's manual says that array_diff() does this:

"Returns an array containing all the entries from array1 that are not present in any of the other arrays."

So the actual array_diff() method would be:

function array_equal($array1, $array2)
{
   $diff1 = array_diff($array1, $array2);
   $diff2 = array_diff($array2, $array1);

   return
   (
      (count($diff1) === 0) &&
      (count($diff2) === 0)
   );
}

However I go with the sort method :D

Mike