5

What's the fastest way to compare if the keys of two arrays are equal?

for eg.

array1:          array2:

'abc' => 46,     'abc' => 46,
'def' => 134,    'def' => 134,
'xyz' => 34,     'xyz' => 34, 

in this case result should be TRUE (same keys)

and:

array1:          array2:

'abc' => 46,     'abc' => 46,
'def' => 134,    'def' => 134,
'qwe' => 34,     'xyz' => 34, 
'xyz' => 34,    

result should be FALSE (some keys differ)

...array_diff_key() returns an empty array

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Alex
  • 66,732
  • 177
  • 439
  • 641
  • 3
    Compare the result of `array_diff_key` to an empty array, and if this is `true` you'll know that both arrays have the same keys. – Yoshi Jun 06 '11 at 13:28
  • should `array('a'=>'b')` return `true` compared to `array('a'=>'c')` ? – Teneff Jun 06 '11 at 13:30
  • @Teneff that's ambiguous, from the question. It depends. If the values of the keys don't matter, then yes, both arrays should return true. If the values do matter, then false. –  Jun 06 '11 at 13:33
  • yes, `true` - meaning they are equal. basically I only want to find out if the arrays have the same keys. @Yoshi: not sure I understand what u mean. array_keys() gives me a empty array and I know my arrays are different... If I compare that to a empty array wouldn't I always get TRUE? – Alex Jun 06 '11 at 13:33
  • Does it really return an empty array??? I've tried you example and it returns array of size 1. I guess you used another example yourself. @Yoshi don't forget that you have to run it both way then! (e.g. `$a = array('a' => 'c'); $b = array('a' => 'c', 'b' => 'f');` would be considered equal according to you) – mkilmanas Jun 06 '11 at 13:35
  • sorry I meant array_diff_key in my comment above – Alex Jun 06 '11 at 13:38
  • Related: [Check if all of several PHP array keys exist](https://stackoverflow.com/q/16974683/2943403) and [What's quicker and better to determine if an array key exists in PHP?](https://stackoverflow.com/q/700227/2943403) and [How to check if multiple array keys exists](https://stackoverflow.com/q/13169588/2943403) – mickmackusa Oct 26 '22 at 21:41

4 Answers4

19

Use array_diff_key, that is what it is for. As you said, it returns an empty array; that is what it is supposed to do.

Given array_diff_key($array1, $array2), it will return an empty array if all of array1's keys exist in array2. To make sure that the arrays are equal, you then need to make sure all of array2's keys exist in array1. If either call returns a non-empty array, you know your array keys aren't equal:

function keys_are_equal($array1, $array2) {
  return !array_diff_key($array1, $array2) && !array_diff_key($array2, $array1);
}
pid
  • 11,472
  • 6
  • 34
  • 63
user229044
  • 232,980
  • 40
  • 330
  • 338
5

Use array_keys to get array of keys and then use array_diff.

OR

Use array_diff_key directly.

Naveed
  • 41,517
  • 32
  • 98
  • 131
4

How about using === instead? You know, the operator for equality?

$array1 = array(
    'abc' => 46,
    'def' => 134,
    'xyz' => 34
);


$array2 = array(
    'abc' => 46,
    'def' => 134,
    'xyz' => 34,
);


var_dump( array_keys( $array1 ) === array_keys( $array2 ) );
Berry Langerak
  • 18,561
  • 4
  • 45
  • 58
0

Less sexy than @user229044's answer leveraging native function calls, I'll offer somewhat of a polyfill for the same process which is optimized to perform the fewest possible cycles by conditionally returning early and never re-checking a given key twice when swapping out the array whose keys are being validated.

Code: (Demo showing keys not being rechecked in the 2nd loop)

function allKeysFoundInBothArrays(array $array1, array $array2): bool
{
    foreach ($array1 as $key => $notUsed) {
        if (!key_exists($key, $array2)) {
            return false;
        }
        unset($array2[$key]);
    }
    foreach ($array2 as $key => $notUsed) {
        if (!key_exists($key, $array1)) {
            return false;
        }
    }
    return true;
}

var_export(allKeysFoundInBothArrays($array1, $array2));
mickmackusa
  • 43,625
  • 12
  • 83
  • 136