20

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?

6
  • 2
    Honestly I'd use a for loop instead. Commented Oct 30, 2011 at 21:29
  • 7
    Did you get this array through mysql_fetch_array by any chance? If so, you can tell it to only return a numeric array. Commented Oct 30, 2011 at 21:30
  • you will have to iterate the whole array and check if the key is not numeric just do nothing and continue. Commented Oct 30, 2011 at 21:31
  • 4
    Your input is broken. Fix it rather than working around it! Commented Oct 30, 2011 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. Commented Oct 30, 2011 at 23:39

4 Answers 4

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().

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

4 Comments

The anonymous function in array_filter could be replaced by the string 'is_int' :)
@Jack Thank's for digging up an ancient answer. Answer expanded.
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.
@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.
11
    foreach($array as $key => $val) {
        if(!is_int($key))
             continue;
        // rest of the logic
    }

3 Comments

yeah its different but OP said integers.
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.
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'
)

Comments

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"
}

1 Comment

This is definitely the best.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.