34

Is there anyway to compare arrays in php using an inbuilt function, short of doing some sort of loop?

$a1 = array(1,2,3);
$a2 = array(1,2,3);

if (array_are_same($a1, $a2)) {
    // code here
}

Btw, the array values will not always be in the same order.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • 4
    What does "the same" mean; do you mean that they contain the same elements *in the same order*, or just that they contain the same elements? For the former, karim79's answer is correct; otherwise, the answers advocating ordinary == will suffice. – Rob May 23 '09 at 16:14
  • What about duplicate values? – hakre Jul 14 '13 at 10:21
  • The best answer (most comprehensive) seems to be the one from @hakre: http://stackoverflow.com/questions/901815/php-compare-array/17638939#17638939 << That should be chosen as the correct answer to this imho. – Jon L. May 27 '14 at 19:01

18 Answers18

45
if ( $a == $b ) {
    echo 'We are the same!';
}
spoulson
  • 21,335
  • 15
  • 77
  • 102
Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
  • 10
    That also requires that the array keys match as well, as per the array comparison example found in the PHP docs: http://php.net/manual/en/language.operators.comparison.php – Jon L. May 10 '11 at 22:24
  • 2
    @JonL. `if ( array_values( $a ) == array_values( $b ) {}` ?? – Eric Holmes May 26 '14 at 16:10
  • 3
    @EricHolmes, as noted in comments on another answer, that only works if order is same: http://stackoverflow.com/questions/901815/php-compare-array/901831?noredirect=1#comment19924354_901830 – Jon L. May 27 '14 at 18:55
  • 1
    See the edit history of the question and you will understand why the answer is correct as per the original question posted on *May 23 '09 at 16:05*. The question was edited by someone else rather than the inquirer on *Jul 14 '13 at 11:43* to add "Btw, the array values will not always be in the same order". – Alan Haggai Alavi May 28 '14 at 02:37
32

Comparing two arrays to have equal values (duplicated or not, type-juggling taking into account) can be done by using array_diff() into both directions:

!array_diff($a, $b) && !array_diff($b, $a);

This gives TRUE if both arrays have the same values (after type-juggling). FALSE otherwise. Examples:

function array_equal_values(array $a, array $b) {
    return !array_diff($a, $b) && !array_diff($b, $a);
}

array_equal_values([1], []);            # FALSE
array_equal_values([], [1]);            # FALSE
array_equal_values(['1'], [1]);         # TRUE
array_equal_values(['1'], [1, 1, '1']); # TRUE

As this example shows, array_diff leaves array keys out of the equation and does not care about the order of values either and neither about if values are duplicated or not.


If duplication has to make a difference, this becomes more tricky. As far as "simple" values are concerned (only string and integer values work), array_count_values() comes into play to gather information about which value is how often inside an array. This information can be easily compared with ==:

array_count_values($a) == array_count_values($b);

This gives TRUE if both arrays have the same values (after type-juggling) for the same amount of time. FALSE otherwise. Examples:

function array_equal_values(array $a, array $b) {
    return array_count_values($a) == array_count_values($b);
}

array_equal_values([2, 1], [1, 2]);           # TRUE
array_equal_values([2, 1, 2], [1, 2, 2]);     # TRUE
array_equal_values(['2', '2'], [2, '2.0']);   # FALSE
array_equal_values(['2.0', '2'], [2, '2.0']); # TRUE

This can be further optimized by comparing the count of the two arrays first which is relatively cheap and a quick test to tell most arrays apart when counting value duplication makes a difference.


These examples so far are partially limited to string and integer values and no strict comparison is possible with array_diff either. More dedicated for strict comparison is array_search. So values need to be counted and indexed so that they can be compared as just turning them into a key (as array_search does) won't make it.

This is a bit more work. However in the end the comparison is the same as earlier:

$count($a) == $count($b);

It's just $count that makes the difference:

    $table = [];
    $count = function (array $array) use (&$table) {
        $exit   = (bool)$table;
        $result = [];
        foreach ($array as $value) {
            $key = array_search($value, $table, true);

            if (FALSE !== $key) {
                if (!isset($result[$key])) {
                    $result[$key] = 1;
                } else {
                    $result[$key]++;
                }
                continue;
            }

            if ($exit) {
                break;
            }

            $key          = count($table);
            $table[$key]  = $value;
            $result[$key] = 1;
        }

        return $result;
    };

This keeps a table of values so that both arrays can use the same index. Also it's possible to exit early the first time in the second array a new value is experienced.

This function can also add the strict context by having an additional parameter. And by adding another additional parameter would then allow to enable looking for duplicates or not. The full example:

function array_equal_values(array $a, array $b, $strict = FALSE, $allow_duplicate_values = TRUE) {

    $add = (int)!$allow_duplicate_values;

    if ($add and count($a) !== count($b)) {
        return FALSE;
    }

    $table = [];
    $count = function (array $array) use (&$table, $add, $strict) {
        $exit   = (bool)$table;
        $result = [];
        foreach ($array as $value) {
            $key = array_search($value, $table, $strict);

            if (FALSE !== $key) {
                if (!isset($result[$key])) {
                    $result[$key] = 1;
                } else {
                    $result[$key] += $add;
                }
                continue;
            }

            if ($exit) {
                break;
            }

            $key          = count($table);
            $table[$key]  = $value;
            $result[$key] = 1;
        }

        return $result;
    };

    return $count($a) == $count($b);
}

Usage Examples:

array_equal_values(['2.0', '2', 2], ['2', '2.0', 2], TRUE);           # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE);        # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE, FALSE); # FALSE
array_equal_values(['2'], ['2'], TRUE, FALSE);                        # TRUE
array_equal_values([2], ['2', 2]);                                    # TRUE
array_equal_values([2], ['2', 2], FALSE);                             # TRUE
array_equal_values([2], ['2', 2], FALSE, TRUE);                       # FALSE
hakre
  • 193,403
  • 52
  • 435
  • 836
  • This answer does not work if one array has a value twice. And the other array much have that value twice as well. – Case Jan 22 '16 at 16:42
  • @Iscariot: That indeed is an interesting scenario not covered. The answer is most likely short to duplicate value comparison as the question is not covering those, too. There is also another differentiation possible: duplicate (n-time) values need to match n-times as well or 1:n-times. – hakre Jan 22 '16 at 21:54
13

@Cleanshooter i'm sorry but this does not do, what it is expected todo: (so does array_diff mentioned in this context)

$a1 = array('one','two');
$a2 = array('one','two','three');

var_dump(count(array_diff($a1, $a2)) === 0); // returns TRUE

(annotation: you cannot use empty on functions before PHP 5.5) in this case the result is true allthough the arrays are different.

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

which does not mean that array_diff is something like: array_get_all_differences. Explained in mathematical sets it computes:

{'one','two'} \ {'one','two','three'} = {}

which means something like all elements from first set without all the elements from second set, which are in the first set. So that

var_dump(array_diff($a2, $a1));

computes to

array(1) { [2]=> string(5) "three" } 

The conclusion is, that you have to do an array_diff in "both ways" to get all "differences" from the two arrays.

hope this helps :)

hakre
  • 193,403
  • 52
  • 435
  • 836
pscheit
  • 2,882
  • 27
  • 29
5

Also you can try this way:

if(serialize($a1) == serialize($a2))
Murz
  • 199
  • 2
  • 9
3

array_intersect() returns an array containing all the common values.

hakre
  • 193,403
  • 52
  • 435
  • 836
moonw
  • 372
  • 2
  • 15
3

Just check $a1 == $a2 -- what's wrong with that?

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 3
    That also requires that the array keys match as well, as per the array comparison example found in the PHP docs: php.net/manual/en/language.operators.comparison.php – Jon L. May 10 '11 at 22:25
  • With the Hint of Jon L. I guess then this is the best to compare array values: array_values($a1) == array_values($a2) – Tyron Jan 15 '13 at 10:24
  • ... and also order must be the same. Depending on what is desirable you might want to sort the arrays first. – NickSoft Nov 24 '13 at 10:57
2

Conclusion from the commentary here:

Comparison of array values being equal (after type juggling) and in the same order only:

array_values($a1) == array_values($a2)

Comparison of array values being equal (after type juggling) and in the same order and array keys being the same and in the same order:

array_values($a1) == array_values($a2) && array_keys($a1) == array_keys($a2)
hakre
  • 193,403
  • 52
  • 435
  • 836
Tyron
  • 1,938
  • 11
  • 30
  • 3
    Wow. I'm moving from C++ to PHP. Big difference. On PHP, the best appropriate answer is buried under 5 screens of "uh, how bout just use 'dis thing here, eh?" On C++, all I see is "well technically, the most correct answer must be this!" – Scott May 12 '13 at 03:10
  • if you want to just compare both keys and values why don't you use $a1 == $a2 – NickSoft Nov 24 '13 at 11:06
1

A speedy method for comparing array values which can be in any order...

function arrays_are_same($array1, $array2) {
    sort($array1);
    sort($array2);
    return $array1==$array2;
}

So for...

    $array1 = array('audio', 'video', 'image');
    $array2 = array('video', 'image', 'audio');

arrays_are_same($array1, $array2) will return TRUE

chichilatte
  • 1,697
  • 19
  • 21
  • The order of the array doesn't matter, according to Example #1 on http://php.net/manual/en/language.operators.comparison.php – Tyron Jan 15 '13 at 10:29
  • Huh? If you do `var_dump(array(1,2,3) == array(3,2,1));` you get `bool(false)`. Same goes with Example #1: `var_dump(standard_array_compare(array(1,2,3), array(3,2,1)));` returns `int(-1)`. – chichilatte Feb 19 '13 at 11:18
1

get the array from user or input the array values.Use sort function to sort both arrays. check using ternary operator. If the both arrays are equal it will print arrays are equal else it will print arrays are not equal. there is no loop iteration here.

sort($a1);
sort($a2);
echo (($a1==$a2) ? "arrays are equal" : "arrays are not equal");
CJ Ramki
  • 2,620
  • 3
  • 25
  • 47
1

If you want to search some array inside a big array of arrays (>10k) then much more quickly is comparing serialized arrays (saved in cache). Example from work with URL:

/**
@return array
*/
function createCache()
{
    $cache = [];
    foreach ($this->listOfUrl() as $url => $args)
    {
        ksort($args);
        $cache['url'][$url] = $args;
        $cache['arr'][crc32(serialize($args))] = $url;
    }
    return $cache;
}

/**
@param array $args
@return string
*/
function searchUrl($args)
{
    ksort($params);
    $crc = crc32(serialize($params));        
    return isset($this->cache['arr'][$crc]) ? $this->cache['arr'][$crc] : NULL;                
} 

/**
@param string $url
@return array
*/
function searchArgs($url)
{
    return isset($this->cache['url'][$url]) ? $this->cache['url'][$url] : NULL;
}
revoke
  • 529
  • 4
  • 9
0

verify that the intersections count is the same as both source arrays

$intersections = array_intersect($a1, $a2);
$equality = (count($a1) == count($a2)) && (count($a2) == count($intersections)) ? true : false;
rcourtna
  • 4,589
  • 5
  • 26
  • 27
0

Compare values of two arrays:

$a = array(1,2,3);
$b = array(1,3,2);

if (array_diff($a, $b) || array_diff($b, $a)) {
    echo 'Not equal';
}else{
    echo 'Equal';
}
1Rhino
  • 298
  • 3
  • 12
0

If you do not care about keys and that just the values then this is the best method to compare values and make sure the duplicates are counted.

$mag = '{"1":"1","2":"2","3":"3","4":"3"}';
$mag_evo = '1|2|3';

$test1 = array_values(json_decode($mag, true));
$test2 = array_values(explode('|', $mag_evo));

if($test1 == $test2) {
    echo 'true';
}

This will not echo true as $mag has 2 values in the array that equal 3.

This works best if you only care about the values and keys and you do not care about duplication. $mag = '{"1":"1","2":"2","3":"3","4":"3"}'; $mag_evo = '1|2|3';

$test1 = json_decode($mag, true);
$test2 = explode('|', $mag_evo);

// There is no difference in either array.  
if(!array_diff($test1, $test2) && !array_diff($test2, $test1)) { 
    echo 'true';
}

This will return true as all values are found in both arrays, but as noted before it does not care about duplication.

Case
  • 4,244
  • 5
  • 35
  • 53
0

this is a simple way to get the difference:

$array1 = [40,10,30,20,50];
$array2 = [10,30];
$result = array_filter(
                       $array1,
                       function($var) use($array2){
                                if(in_array($var, $array2)){
                                   return $var;
                                }
                         }
             );
print_r($result); //Array ( [0] => 10 [1] => 30 )
Ibnul Husainan
  • 221
  • 3
  • 6
0

I just wanted to contribute that: echo var_export([1 => 2, 0 => 1, 3] == [1, 2, 3], 1);

Echoes true. Therefore the == operator does not check that the elements in the array are in the same order, in the manner you would expect. Meaning array_values of the above are [2, 1, 3] and [1, 2, 3]. Yet because their keys have the same values, they are equal according to == operator. (Remember [1, 2, 3] creates this array: [0 => 1, 1 => 2, 2 => 3])

-1

try this :

$array1 = array("street" => array("Althan"), "city"   => "surat", "state"  => "guj", "county" => "india");
        $array2  = array("street" => array("Althan"), "city"   => "surat", "state"  => "guj", "county" => "india");

    if (array_compare($array1, $array2))
    {
             echo "<pre>";
             print_r("succsses..!");
             echo "</pre>";
             exit;

    }
    else
    {
            echo "<pre>";
            print_r("Faild..!");
            echo "</pre>";
            exit;
    }

    function array_compare($op1, $op2)
    {

            foreach ($op1 as $key => $val)
            {
                    if (is_array($val))
                    {
                            if (array_compare($val, $op2[$key]) === FALSE)
                                    return false;
                    }
                    else
                    {

                            if (!array_key_exists($key, $op2))
                            {
                                    return false; // uncomparable
                            }
                            elseif ($val < $op2[$key])
                            {
                                    return false;
                            }
                            elseif ($val > $op2[$key])
                            {
                                    return false;
                            }
                    }
            }
            return true; // $op1 == $op2
    }
Chintan
  • 1,204
  • 1
  • 8
  • 22
-2
if(count($a1) == count($a2)){
    $result= array_intersect($a1, $a2);
    if(count($a1) == count($result))
        echo 'the same';
    else
        echo 'a1 different than a2';
} else
        echo 'a1 different than a2';
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
  • array_intersect will not compare the order of values. but comparing the size of an array before the actual compare might be a good optimisation. Also array intersect will not work well for repeating values - array_intersect(array("value1", "value1", "value2"), array("value1", "value2", "value2")) - tis will say that the 2 arrays are the same, but they are not. – NickSoft Nov 24 '13 at 11:03
-2

As far as I can tell, there isn't a single built-in function that'll do it for you, however, something like:

if (count($a) == count($b) && (!count(array_diff($a, $b))) {
  // The arrays are the same
}

Should do the trick

pnomolos
  • 836
  • 12
  • 15