18

Much like rtrim() to a string, how do I remove the empty elements of an array only after the last non-empty element towards the end of the array while avoiding a for or similar loop and possibly using PHP's array functions instead?

I'm actually looking for the fastest/most efficient/elegant way, but if this is not possible without a for or similar loop or I'm mistaken about "fast/efficient/elegant" especially with PHP's array functions then I'd be more than happy to learn/know what's best. Thanks.

Other assumptions:

  1. There can be a series of single or consecutive empty elements before the last non-empty element in the array.
  2. No need to worry about an empty array, but if this case is covered it's totally fine.

For example:

Array
(
    [0] => ""
    [1] => "text"
    [2] => "text"
    [3] => ""
    [4] => "text"
    [5] => ""
    [6] => ""
    [7] => "text"
    [8] => ""
    [9] => ""
)

would end up being:

Array
(
    [0] => ""
    [1] => "text"
    [2] => "text"
    [3] => ""
    [4] => "text"
    [5] => ""
    [6] => ""
    [7] => "text"
)

and

Array
(
    [0] => "text"
    [1] => "text"
    [2] => "text"
    [3] => "text"
    [4] => "text"
    [5] => "text"
    [6] => "text"
    [7] => ""
    [8] => ""
    [9] => ""
)

would end up being:

Array
(
    [0] => "text"
    [1] => "text"
    [2] => "text"
    [3] => "text"
    [4] => "text"
    [5] => "text"
    [6] => "text"
)
Ana Ban
  • 1,395
  • 4
  • 21
  • 29

5 Answers5

18

It's like you wrote it in your question: As long as the last value is an empty string, remove it from the array:

while ("" === end($array))
{
    array_pop($array);
}

Edit: I have no clue how serious this is, however for the fun, I've come up with this which does not uses any loop in user-code, however, loops are involved for sure inside PHP C functions. Probably this can make a difference, no idea, to enjoy responsively:

$array = array_slice($array, 0, key(array_reverse(array_diff($array, array("")), 1))+1);

How it works:

  • Get an array with all values that are not in array(""). Keys will be preserved (that's the important part, the keys in your array are 0-n).
  • Get the key of the last element.
  • Slice the array from start to that position.
hakre
  • 193,403
  • 52
  • 435
  • 836
  • sweet jellybeans yes! how could've i missed that? hakre yerra legend. thanks! (sorry have to wait 4 more minutes to accept the answer..) and @webarto, at least it doesn't always have to loop through the whole array. – Ana Ban Dec 29 '11 at 02:22
  • @AnaBan, in any case it doesn't :) +1 – Dejan Marjanović Dec 29 '11 at 02:27
  • @webarto i see.. what if the whole array is filled with empty values? its count would still be > 0.. hm.. or am i getting this wrong again? thanks, am learnin a lot.. – Ana Ban Dec 29 '11 at 02:30
  • @Ana Ban: If the whole array is empty, than looking from the back means it would take the longest possible time. PHP.net has a long, [long list of array functions](http://de.php.net/manual/en/ref.array.php), read through it, it's worth anyway, maybe there is some gem in there that will do it. I'll look as well. – hakre Dec 29 '11 at 02:32
  • totally, been lookin through it lots, thanks much! anyways, the whole-array-empty case is an extreme one, so i'll leave it at that for now. thanks again – Ana Ban Dec 29 '11 at 02:35
  • 1
    @AnaBan: With "only" three build in array functions, I was able to do it. See the updated answer. – hakre Dec 29 '11 at 02:46
  • oh my word that's sexy! the beauty of the edit is it saved me 1 more step, coz that `key`'s exactly what am lookin fer! absolutely spot on! – Ana Ban Dec 29 '11 at 03:08
  • Seems this does not work for empty entries., If I do `while (empty(end($array)))` I get ***Can't use function return value in write context*** – mplungjan Sep 13 '13 at 05:59
  • 1
    @mplungjan: You most likely meant `while(!end($array))` however, if you want to understand that error in more detail, see http://stackoverflow.com/q/1075534/367456 and if you want to understand why you're using `empty` wrong see http://stackoverflow.com/a/4328049/367456 – hakre Sep 17 '13 at 06:43
  • No I meant what I said. Your code only works if there is an actual space in the array. Thanks for the explanation. I ended up reversing like here: http://stackoverflow.com/a/8663367/295783 – mplungjan Sep 17 '13 at 06:55
  • What's great about the `while` solution, is that's it's clean and instantly understandable. I can't understand the array function chain after only 5 seconds, so TL;DR. – CJ Dennis Feb 15 '18 at 23:45
  • 1
    one day i got forever while loop. To avoid this, i made adjustment to your solution: while (count($array)>0 && "" == end($array)) { array_pop($array); } – Tomas Šivickas Apr 19 '21 at 16:51
  • @TomasŠivickas: Always use `===` for the comparison (strict equal) otherwise you're asking for trouble in PHP (well most often, here in the while for sure). – hakre Apr 19 '21 at 17:06
4

Use trim() or rtrim() as you need it:

explode( '·', trim( implode( '·', $test ), '·') );

It changes …

Array
(
    [0] => 
    [1] => text
    [2] => text
    [3] => 
    [4] => text
    [5] => 
    [6] => 
    [7] => text
    [8] => 
)

… to …

Array
(
    [0] => text
    [1] => text
    [2] => 
    [3] => text
    [4] => 
    [5] => 
    [6] => text
)
fuxia
  • 62,923
  • 6
  • 54
  • 62
  • 4
    What if your delimiter you set in "implode" is used within one of the values within the original array? – danielrsmith Dec 29 '11 at 02:25
  • Then it will break. If you cannot control the content, you’ll need @hakre’s solution. – fuxia Dec 29 '11 at 02:27
  • Right - I was just pointing out that you really can't use array to string manipulation when you need to go back and forth from array like this. – danielrsmith Dec 29 '11 at 02:29
1
while (!end($array)) { array_pop($array); };
andrei
  • 1,353
  • 15
  • 24
1
function array_rtrim($array)
{
    $array = array_reverse($array);
    foreach ($array as $key => $value)
    if ((string) $value === '') unset($array[$key]); else break 1;
    return array_reverse($array);
}

...

$array = array('', 1, 2, 3, '', 0, '', '');
print_r(array_rtrim($array));

...

Array
(
    [0] => 
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 
    [5] => 0
)
Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
-1

Once you rebuild your array, use array_values to rebuild the indexes.

array_walk_recursive('unset_any_null_values_function', $array);

print_r(array_values($array));
Nikola K.
  • 7,093
  • 13
  • 31
  • 39
Philip
  • 4,592
  • 2
  • 20
  • 28