Reputation: 41
Trying to delete all elements in the array (given below) which are less then 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>';
?>
However, the result is the following:
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
Quite confused why not all the elements which are less then 0 are removed from the array. Any thoughts on this?
Upvotes: 4
Views: 118
Reputation: 79014
Adding to the excellent foreach
and array_filter
answers (which detail the issue), using your existing loop, just count
first so that it can't change each 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]);
}
}
Upvotes: 2
Reputation: 41820
If you really need to do it in a loop, you can avoid that problem by using a foreach loop instead.
foreach ($arr as $key => $value) {
if ($value < 0) {
unset($arr[$key]);
}
}
Removing elements as you iterate shouldn't cause any problems this way.
Upvotes: 4
Reputation: 19764
You could do this using array_filter()
. The second parameter is an anonymous function that takes as argument an element of the array. Inside, you have to determine weither it should be kept or not.
$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>';
Outputs :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
Upvotes: 2
Reputation: 12135
You are iterating using count($arr)
which is reevaluated after each iteration. Since you remove an item, the array gets shorter. At the same time you increment your iterator. This works out until you reach the second last item, where deleting that item and increment the counter makes the loop condition false, thus skipping the last elements.
You can do an echo
in the loop to print $i
and count($arr)
to see the details.
Upvotes: 3
Reputation: 21575
This is because you are manipulating the array while you are positively iterating through it, which can make it off-set and skip elements. One common way to solve this is to do the loop backwards:
$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>';
Upvotes: 2
Reputation: 164946
This is what usually happens when you remove elements while iterating forwards through a collection. You end up missing elements because you're trying to iterate a moving target. One solution would be to iterate backwards
for ($i = count($arr) - 1; $i >= 0; $i--)
Another would be to simply use array_filter
to create a new array
$newArr = array_filter($arr, function($num) {
return $num >= 0;
});
Upvotes: 4