52

if i filter an array with array_filter to eliminate null values, keys are preserved and this generated "holes" in the array. Eg:

The filtered version of
    [0] => 'foo'
    [1] =>  null
    [2] => 'bar'
is 
    [0] => 'foo'
    [2] => 'bar'

How can i get, instead

[0] => 'foo'
[1] => 'bar'

?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
pistacchio
  • 56,889
  • 107
  • 278
  • 420
  • Possible duplicate of [After array\_filter(), how can I reset the keys to go in numerical order starting at 0](https://stackoverflow.com/questions/3401850/after-array-filter-how-can-i-reset-the-keys-to-go-in-numerical-order-starting) – ggorlen Jan 28 '19 at 21:51

2 Answers2

97

You could use array_values after filtering to get the values.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
9

Using this input:

$array=['foo',NULL,'bar',0,false,null,'0',''];

There are a few ways you could do it. Demo

It's slightly off-topic to bring up array_filter's greedy default behavior, but if you are googling to this page, this is probably important information relevant to your project/task:

var_export(array_values(array_filter($array)));  // NOT GOOD!!!!!

Bad Output:

array (
  0 => 'foo',
  1 => 'bar',
)

Now for the ways that will work:

Method #1: (array_values(), array_filter() w/ !is_null())

var_export(array_values(array_filter($array,function($v){return !is_null($v);})));  // good

Method #2: (foreach(), auto-indexed array, !==null)

foreach($array as $v){
    if($v!==null){$result[]=$v;}
}
var_export($result);  // good

Method #3: (array_walk(), auto-index array, !is_null())

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});
var_export($filtered);  // good

All three methods provide the following "null-free" output:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

From PHP7.4, you can even perform a "repack" like this: (the splat operator requires numeric keys)

Code: (Demo)

$array = ['foo', NULL, 'bar', 0, false, null, '0', ''];

$array = [...array_filter($array)];

var_export($array);

Output:

array (
  0 => 'foo',
  1 => 'bar',
)

... but as it turns out, "repacking" with the splat operator is far less efficient than calling array_values().

mickmackusa
  • 43,625
  • 12
  • 83
  • 136