179

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 
1

7 Answers 7

309
echo array_search("car",array_keys($a)); 
Sign up to request clarification or add additional context in comments.

5 Comments

Does PHP guarantee the order of an associative array?
@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.
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.
This DOES NOT work if the associative array is mixed, for array("val1", "val2", "car" => "val3") it will produce 0, which is wrong...
How is this any different from @quantamSoup's answer?
37
$blue_keys = array_search("blue", array_keys($a)); 

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

Comments

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))); 

2 Comments

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).
@ShaunCockerill right! Updated my answer, thanks for pointing this out!
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.

1 Comment

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
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)));  

Comments

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.

Comments

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++; } } } 

3 Comments

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.
This is probably faster than array_search, which does a sort first and so it painfully slow.
Ah, but the built in code is precompiled, and the search will most likely be a binary search (assuming it does sort items first).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.