37

I'm trying to obtain the first key of an associative array, without creating a temporary variable via array_keys() or the like, to pass by reference. Unfortunately both reset() and array_shift() take the array argument by reference, so neither seem to be viable results.

With PHP 5.4 I'll be in heaven; array_keys($array)[0];, but unfortunately this of course is not an option either.

I could create a function to serve the purpose, but I can only imagine there is some concoction of PHP's array_* functions that will produce the desired result in a single statement, that I cannot think of or come up with.

So:

$array = array('foo' => 'bar', 'hello' => 'world');

$firstKey = assorted_functions($array); // $firstKey = 'foo'

The reason for the "no reference" clause in my question is only for the fact that I assume array_keys() will be required (if there is a way passing by reference, please fire away)

I'd use key(), but that requires a reset() as I'm not sure where the pointer will be at the time of this operation.


Addendum

I'm following up on a realization I had recently: as I mentioned in the comments, it'll use the memory all the same, so if that's a concern, this question hath no solution.

$a = range(0,99999);
var_dump(memory_get_peak_usage()); // int(8644416)
$k = array_keys($a)[0];
var_dump(memory_get_peak_usage()); // int(17168824)

I knew this, as PHP doesn't have such optimization capabilities, but figured it warranted explicit mention.

The brevity of the accepted answer is nice though, and'll work if you're working with reasonably sized arrays.

5
  • 1
    I've got a vague hackish idea of foreach($array as &$key) { return $key; } possibly accomplishing what you want, but I'm too lazy to test it, and not quite sure what you want. Commented Jul 14, 2011 at 18:55
  • @Marc B foreach($array as $key=>$value) { return $key; } should work Commented Jul 14, 2011 at 18:59
  • @Marc B - Trying for a single statement to return the value. I could wrap a foreach in a call_user_func(function(){}) but that's a little crazy. Commented Jul 14, 2011 at 18:59
  • I just realized: I don't think it matters how you slice it because IIRC now, array_keys() creates a copy of the array keys in memory anyway, even with an immediate dereferencing. The single-expression brevity is nice, but the memory consumption still happens. Commented Feb 5, 2013 at 0:38
  • I just realized something else; this question has self-deprecated, as if you're still using <= 5.3, you've got problems. Commented Apr 14, 2014 at 5:05

5 Answers 5

64

Since PHP 7.3: $firstKey = array_key_first($array);.


Although array_shift(array_keys($array)); will work, current(array_keys($array)); is faster as it doesn't advance the internal pointer.

And as @TomcatExodus noted, array_shift(); expects an array passed by reference, so the first example will issue an error. Best to stick with current();

Sign up to request clarification or add additional context in comments.

8 Comments

Bingo. Thank you much on current(array_keys()). Just for future reference, an array produced by array_keys() or array_values() is of course new, and therefore it's pointer is always at the first element, correct?
Excellent; Thanks again. I must need more coffee, because the more I look at the answer, the more glaringly obvious it seems :) Oh, and a note on array_shift(); it doesn't. PHP 5.3.6 with error_reporting(-1) issues an error.
is key($array) not faster?
Maybe. It'll do the job. Use whatever you want. OP wanted something other than key() so this is it.
current(array_keys($array)); is faster? or the following is faster foreach($array as $key => $val){ echo $key;break;}
|
19

You can use reset and key:

reset( $array );
$first_key = key( $array );

or, you can use a function:

function firstIndex($a) { foreach ($a as $k => $v) return $k; }
$key = firstIndex( $array );

3 Comments

Thanks @Dark Slipstream - Trying to accomplish in a single statement, no reset().
You said you can use a function, use that.
"could", but don't want to, especially given the elegant solution. Thanks though :)
1
array_shift(array_keys($array))

5 Comments

Thanks @RiaD - Strict standards, array_shift() requires an array by reference, it's a no go.
@Tomcat. It's get new array. So your array will be ok. Or it is trigger some errors/notices ?
Sorry for the ambiguity; yea it issues a notice Strict Standards
OK, thank you, I will know it next time:) [Have not PHP to test]
array_shift takes array by reference so it will throw error in php 5.4
1

each() still a temporary required, but potentially a much smaller overhead than using array_keys().

2 Comments

Thanks @Orbling - True, there's a plethora of ways using a temporary, but that's what I'm trying to avoid. My struggle has gone from practical to academic :P
Also, perhaps should have mentioned; the array is not very long, just very deep. The first dimension will likely have 3 - 5 elements, so while array_keys() is more overhead, it's not producing an enormous array.
0

What about using array_slice (in combination with array_keys for associative arrays)?

$a = range(0,999999);
var_dump(memory_get_peak_usage());
$k = array_keys(array_slice($a, 0, 1, TRUE))[0];
var_dump(memory_get_peak_usage());
var_dump($k);
$k = array_keys($a)[0];
var_dump(memory_get_peak_usage());

Gives as output (at least with me):

int(36354360)
int(36355112)
int(0)
int(72006024)
int(0)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.