I have an array with 2 kinds of keys, strings and integers. I want to do foreach()
on this array and want to do it for numeric keys only. What is the most elegant way of doing it?
Asked
Active
Viewed 1.7k times
20

Michael Berkowski
- 267,341
- 46
- 444
- 390

henrijs
- 1,010
- 2
- 11
- 19
-
2Honestly I'd use a for loop instead. – BoltClock Oct 30 '11 at 21:29
-
7Did you get this array through `mysql_fetch_array` by any chance? If so, you can tell it to only return a numeric array. – Felix Kling Oct 30 '11 at 21:30
-
you will have to iterate the whole array and check if the key is not numeric just do nothing and continue. – Ehtesham Oct 30 '11 at 21:31
-
4Your input is broken. Fix it rather than working around it! – Lightness Races in Orbit Oct 30 '11 at 21:35
-
thank you, I was thinking there is some magic function in php, but this will do just fine. and sorry for numeric/integer mess. – henrijs Oct 30 '11 at 23:39
-
also, about "Your input is broken"... i'm getting this array in template variable and wanted to hack it right before rendering, so i probably wont have this issue if doing things properly in preprocess or something. – henrijs Oct 30 '11 at 23:42
4 Answers
30
Here's a complicated method using array_filter()
to return the numeric keys then iterate over them.
// $input_array is your original array with numeric and string keys
// array_filter() returns an array of the numeric keys
// Use an anonymous function if logic beyond a simple built-in filtering function is needed
$numerickeys = array_filter(array_keys($input_array), function($k) {return is_int($k);});
// But in this simple case where the filter function is a plain
// built-in function requiring one argument, it can be passed as a string:
// Really, this is all that's needed:
$numerickeys = array_filter(array_keys($input_array), 'is_int');
foreach ($numerickeys as $key) {
// do something with $input_array[$key']
}
It's much easier though to just foreach over everything:
foreach ($input_array as $key => $val) {
if (is_int($key)) {
// do stuff
}
}
Edit Misread original post and thought I saw "numeric" rather than "integer" keys. Updated to use is_int()
rather than is_numeric()
.

Michael Berkowski
- 267,341
- 46
- 444
- 390
-
2The anonymous function in `array_filter` could be replaced by the string `'is_int'` :) – Ja͢ck Apr 09 '13 at 06:59
-
@Jack Thank's for digging up an ancient answer. Answer expanded. – Michael Berkowski Apr 09 '13 at 10:57
-
But how efficient do you think think this might be? Many times worse than `foreach(*){if(is_int)(do stuff;)}` Or about the same? Based on the function's description, I would have to say this is at least 2 times more processor intensive, and that is not even taking into account the creation of a whole new variable. – Jonathon May 02 '13 at 18:15
-
@JonathonWisnoski Whenever efficiency is a real concern, setup a benchmark to test it. Anonymous functions as in the first sample are generally slower than `foreach` loops, often by a lot. The second may be a bit faster than the first, calling bare `is_int()` as a callback. – Michael Berkowski May 02 '13 at 18:21
11
foreach($array as $key => $val) {
if(!is_int($key))
continue;
// rest of the logic
}

Ehtesham
- 2,967
- 1
- 18
- 20
-
-
True, they do (and it's possible that `int` is what they meant in practice). However, `numeric` is used several times, including the question title. – Jared Farrish Oct 30 '11 at 21:39
-
2Actually, it doesn't matter. [PHP always stores numeric keys as ints.](http://stackoverflow.com/questions/4100488/a-numeric-string-as-array-key-in-php/4100765#4100765) – Oct 30 '11 at 21:40
6
This one-liner returns a new array with the values and its numeric keys:
$new_array = array_filter($my_array, 'is_int', ARRAY_FILTER_USE_KEY);
so if we have this:
array(
'fruit' => 'banana'
1 => 'papaya'
)
..we get this:
array(
1 => 'papaya'
)

Ignacio Segura
- 678
- 8
- 15
1
Using array_filter you must aware if you have value that similar as FALSE.
This is my solution:
function filterArrayKeyInteger(Array $array) {
$integer = array_filter($array, function ($key) {
if ($key === 0 || is_int($key)) {
return true;
}
}, ARRAY_FILTER_USE_KEY);
return array_intersect_key($array, $integer);
}
$a = [0, false, 'aa','bb', 'cc', 'dd' => 'dd', '9.9' => 9.9];
$b = filterArrayKeyInteger($a);
Result of vardump
var_dump(a): array(7) {
[0]=>
int(0)
[1]=>
bool(false)
[2]=>
string(2) "aa"
[3]=>
string(2) "bb"
[4]=>
string(2) "cc"
["dd"]=>
string(2) "dd"
["9.9"]=>
float(9.9)
}
var_dump(b): array(5) {
[0]=>
int(0)
[1]=>
bool(false)
[2]=>
string(2) "aa"
[3]=>
string(2) "bb"
[4]=>
string(2) "cc"
}

IjorTengab
- 41
- 2