Using unset () in an array to remove items

Trying to remove all elements in an array (below) that are less than 0 using the following code:

 <?php 
       $arr=array(1,2,3,4,5,-6,-7,-8,-9,-10);

        for ($i=0;$i<count($arr);$i++){
                if ($arr[$i]<0) {
                unset($arr[$i]);
                }
        }

    var_dump($arr);

    echo '<pre>', print_r($arr), '</pre>';

    ?>

strong text

However, the result is as follows:

array(7) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [8]=> int(-9) [9]=> int(-10) }
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [8] => -9
    [9] => -10
)
1

It is rather vague why not all elements that are less than 0 are removed from the array. Any thoughts on this? thanks in advance.

+4
source share
6 answers

This usually happens when you delete items during iteration forward through the collection. You lose elements because you are trying to iterate over a moving target. One solution would be to iterate back

for ($i = count($arr) - 1; $i >= 0; $i--)

Another would be simple to use array_filterto create a new array

$newArr = array_filter($arr, function($num) {
    return $num >= 0;
});
+4
source

, , foreach.

foreach ($arr as $key => $value) {
    if ($value < 0) {
        unset($arr[$key]);
    }
}

.

+4

count($arr), . , . . , , , .

echo $i count($arr), .

+3

, array_filter(). - , . , .

$arr=array(1,2,3,4,5,-6,-7,-8,-9,-10);
$arr = array_filter($arr, function($e) {
    return $e >= 0 ; // keep only element greater than zero
});
echo '<pre>', print_r($arr), '</pre>';

:

array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}
+2

This is because you are manipulating the array when you positively repeat it, which can make it disconnected and skip elements. One common way to solve this is to loop back:

   $arr=array(1,2,3,4,5,-6,-7,-8,-9,-10);

    for ($i=count($arr)-1;$i>=0;$i--){
            if ($arr[$i]<0) {
            unset($arr[$i]);
            }
    }

var_dump($arr);

echo '<pre>', print_r($arr), '</pre>';
+2
source

Adding to the excellent answers foreachand array_filter(which describe the problem in detail) using the existing loop, just countfirst so that it cannot change every iteration:

$arr=array(1,2,3,4,5,-6,-7,-8,-9,-10);

$c = count($arr);

for ($i=0; $i<$c; $i++){
    if ($arr[$i]<0) {
        unset($arr[$i]);
    }
}
+2
source

Source: https://habr.com/ru/post/1693660/


All Articles