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?
4 Answers
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().
4 Comments
Ja͢ck
The anonymous function in
array_filter could be replaced by the string 'is_int' :)Michael Berkowski
@Jack Thank's for digging up an ancient answer. Answer expanded.
Jonathon
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.Michael Berkowski
@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. foreach($array as $key => $val) {
if(!is_int($key))
continue;
// rest of the logic
}
3 Comments
Ehtesham
yeah its different but OP said integers.
Jared Farrish
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.Actually, it doesn't matter. PHP always stores numeric keys as ints.
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"
}
1 Comment
Theodore R. Smith
This is definitely the best.
mysql_fetch_arrayby any chance? If so, you can tell it to only return a numeric array.