174

I have an associative array and I need to find the numeric position of a key. I could loop through the array manually to find it, but is there a better way build into PHP?

$a = array(
  'blue'   => 'nice',
  'car'    => 'fast',
  'number' => 'none'
);

// echo (find numeric index of $a['car']); // output: 1
Wes Foster
  • 8,770
  • 5
  • 42
  • 62
n00b
  • 16,088
  • 21
  • 56
  • 72
  • Does this answer your question? [Get the index of a certain value in an array in PHP](https://stackoverflow.com/questions/2959222/get-the-index-of-a-certain-value-in-an-array-in-php) – TylerH Jan 25 '23 at 19:26

7 Answers7

305
echo array_search("car",array_keys($a));
Fosco
  • 38,138
  • 7
  • 87
  • 101
  • 7
    Does PHP guarantee the order of an associative array? – Kevin Burke May 01 '12 at 21:50
  • 9
    @KevinBurke It's not going to re-order it unless you use a sort function. Not sure what sort of guarantee you're looking for, but it's not like the JavaScript model where there is no static order to associative arrays. – Fosco May 01 '12 at 23:20
  • 7
    The indexes given by "array_keys" will not necessarily match the index of the original array. For example, if you have altered the array by using "unset" or a number of other functions, there will be a gap left in the index of the original array, but array_keys will produce a new array. – SEoF Feb 13 '13 at 14:49
  • 5
    This DOES NOT work if the associative array is mixed, for `array("val1", "val2", "car" => "val3")` it will produce `0`, which is wrong... – Xriuk Feb 10 '18 at 11:12
  • How is this any different from [@quantamSoup's answer?](https://stackoverflow.com/a/3365780/6368005) – Mystical Jan 21 '19 at 00:17
38
$blue_keys = array_search("blue", array_keys($a));

http://php.net/manual/en/function.array-keys.php

quantumSoup
  • 27,197
  • 9
  • 43
  • 57
5

While Fosco's answer is not wrong there is a case to be considered with this one: mixed arrays. Imagine I have an array like this:

$a = array(
  "nice",
  "car" => "fast",
  "none"
);

Now, PHP allows this kind of syntax but it has one problem: if I run Fosco's code I get 0 which is wrong for me, but why this happens?
Because when doing comparisons between strings and integers PHP converts strings to integers (and this is kinda stupid in my opinion), so when array_search() searches for the index it stops at the first one because apparently ("car" == 0) is true.
Setting array_search() to strict mode won't solve the problem because then array_search("0", array_keys($a)) would return false even if an element with index 0 exists.
So my solution just converts all indexes from array_keys() to strings and then compares them correctly:

echo array_search("car", array_map("strval", array_keys($a)));

Prints 1, which is correct.

EDIT:
As Shaun pointed out in the comment below, the same thing applies to the index value, if you happen to search for an int index like this:

$a = array(
  "foo" => "bar",
  "nice",
  "car" => "fast",
  "none"
);
$ind = 0;
echo array_search($ind, array_map("strval", array_keys($a)));

You will always get 0, which is wrong, so the solution would be to cast the index (if you use a variable) to a string like this:

$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));
Xriuk
  • 429
  • 5
  • 16
  • 2
    When passing a variable, you should also cast it as a string, as passing zero to an associative array would have the same negative effect. For example: `var_dump(array_search(0, array_map("strval", array_keys($a))));` will always output `int (0)`, rather than `bool (false)`. – Shaun Cockerill Mar 07 '18 at 02:02
  • @ShaunCockerill right! Updated my answer, thanks for pointing this out! – Xriuk Mar 21 '18 at 17:20
3

The solution with array_search would be really heavy, and it's unnecessary to use straight search in this situation.

Much better solution would be:

$keyIndexOfWhichYouAreTryingToFind = 'c';
$array = [
    'a' => 'b',
    'c' => 'd'
];
$index = array_flip(array_keys($array))[$keyIndexOfWhichYouAreTryingToFind];

This type of search would have much better performance on big arrays.

nojitsi
  • 351
  • 3
  • 13
  • 1
    array flip is not O(n) = 1. Although your solution is better in terms of performance,, which I vote as a better solution. it is not truly O(n) = 1 – Stanley Aloh May 17 '22 at 21:08
2

  $a = array(
      'blue' => 'nice',
      'car' => 'fast',
      'number' => 'none'
  );  
var_dump(array_search('car', array_keys($a)));
var_dump(array_search('blue', array_keys($a)));
var_dump(array_search('number', array_keys($a)));

Asterión
  • 21
  • 1
1

All solutions based on array_keys don't work for mixed arrays. Solution is simple:

echo array_search($needle,array_keys($haystack), true);

From php.net: If the third parameter strict is set to TRUE then the array_search() function will search for identical elements in the haystack. This means it will also perform a strict type comparison of the needle in the haystack, and objects must be the same instance.

MrBlc
  • 43
  • 3
0

a solution i came up with... probably pretty inefficient in comparison tho Fosco's solution:

 protected function getFirstPosition(array$array, $content, $key = true) {

  $index = 0;
  if ($key) {
   foreach ($array as $key => $value) {
    if ($key == $content) {
     return $index;
    }
    $index++;
   }
  } else {
   foreach ($array as $key => $value) {
    if ($value == $content) {
     return $index;
    }
    $index++;
   }
  }
 }
n00b
  • 16,088
  • 21
  • 56
  • 72
  • 3
    Yeah, PHP has thousands of builtin functions for a reason. These are *usually* much faster than equivalent logic written out the long way in PHP code. – Bill Karwin Jul 29 '10 at 18:37
  • 3
    This is probably faster than `array_search`, which does a sort first and so it painfully slow. – Alasdair Jan 25 '12 at 05:55
  • Ah, but the built in code is precompiled, and the search will most likely be a binary search (assuming it does sort items first). – SEoF Feb 13 '13 at 14:42