21

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.

1
  • How should the code handle situations where arrays have more than one instance of the same value, for example array(1, 2, 3) vs array(1, 2, 3, 1)? Some of the answers will return true, others false. Also, some will return inconsistent results due to short-circuiting via count(), and will return false in the first example but true if comparing array(1, 2, 3, 1) with array(1, 2, 3, 2). My guess is that this doesn't apply in your situation, but for anyone looking for an answer where duplicate entries may exist, care must be taken to use an algorithm that meets your specific requirements. Commented Jul 8, 2019 at 13:08

8 Answers 8

32

array_diff looks like an option:

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

or as an oneliner in your code:

if(!array_diff($a1, $a2) && !array_diff($a2, $a1)) doSomething();
Sign up to request clarification or add additional context in comments.

9 Comments

You can use empty only with varliables.
gumbo: no, you can use it on arrays just fine. taken from <php.net/empty>: “The following things are considered to be empty: # array() (an empty array)”
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).
@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 docs.php.net/empty
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)
|
10

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.

4 Comments

as I am such a lazy guy, I would still prefer a one-liner that I can pull out and use.
@Ngu Soon Hui - so wrap Gumbo's code into a function (array_equals($arr1,$arr2))?
It would be helpful if the down-voter commented on why he voted my answer down.
@Gumbo Maybe, because he or she is a sick prick (sorry! :~), and that's why he or she downvoted a perfectly valid and professionally written answer? :]
3

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

2 Comments

+1 that's a better way to do it. I found that issue today and ended up using !array_diff($a,$b) && !array_diff($b,$a). Not the best solution, but it does work.
A side note: Though, this is out of OP's question, it is worth to remember, that using array_diff() (and similar like array_intersect()) will fail on multidimensional arrays (PHP notice: Array to string conversion), while using simple array operators of == and === will work on such arrays without any problems.
1

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.

5 Comments

Anyone know the details on performance difference between a diff and a sort in php?
if (array_diff($a, $b)) {} would do. empty array evaluate to false.
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: and is there a reason to care?
@SilentGhost: Not if you have infinite time and space. But who has that?
1

If the arrays being compared consist of only strings and/or integers, array_count_values allows you to compare the arrays quickly (in O(n) time vs O(n log n) for sorting) by verifying that both arrays contain the same values and that each value occurs the same # of times in both arrays.

if(array_count_values($a1) == array_count_values($a2)) {
    //arrays are equal
}

Comments

0

You can use array_intersect() instead of array_diff():

$a = array('4','5','2');
$b = array('2','4','5');
$ca = count($a);
$cb = count($b);
$array_equal = ( $ca == $cb && $ca == count(array_intersect($a, $b)) );

Performance wise. solution, where two factors are important:

  • the more often arrays are matching, the more array_intersect() is fast.
  • the more arrays are big (more than 10 values), the more array_intersect() is fast.

Depending on these factors, one method can be two or three time faster than the other. For big arrays with few (or no) matching combinations, or for little arrays with lots of matching, both methods are equivalent.

However, the sort method is always faster, except in the case with little arrays with few or no matching combinations. In this case the array_diff() method is 30% faster.

1 Comment

Formatting notice: You used poorly written HTML instead of Markdown (fixed) and you seems to be not liking capital letters in the beginning of each section (fixed). So in general, I should downvote your laziness! :] But, on the other hand, you provided an exceptional and interesting answer, so that's fine! :]
0

You only need to compare one-way using array_diff() and use count() for the inverted relationship.

if (count($a1) == count($a2) && !array_diff($a1, $a2)) {
    // equal arrays
}

1 Comment

Down-voting as a general solution, as this will only work if both arrays are unique. It will not give the correct result if either array contains more than one instance of the same value.
0

As an addition to the accepted reply from @knittl

To cover the case, when one of the arrays has additional members:

function areEqualIfOrderIgnored(array $a1, array $a2): bool
{
    if (
        ! array_diff($a1, $a2)
        && ! array_diff($a2, $a1)
        && count($a1) === count($a2)
    ) {
        return true;
    }

    return false;
}

Or one line, as requested (but not nice)

if (! array_diff($a1, $a2) && ! array_diff($a2, $a1) && count($a1) === count($a2)) {do smth}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.