简体   繁体   English

尽管条件仍然为真,为什么这个 for 循环似乎没有执行?

[英]Why doesn't this for loop seem to execute although the condition is still true?

In the following SSCCE, why isn't the for loop being executed for $a greater than 3, although the condition should let it execute till $a becomes 5.在下面的 SSCCE 中,为什么不for大于 3 的$a执行for循环,尽管条件应该让它执行直到$a变为 5。

And the output of the last statement is even more weird.而最后一条语句的输出就更奇怪了。

What I am trying to achieve is that I want to delete the elements have the Select one value for the element/variable word , such that the resulting array is:我想要实现的是,我想删除具有Select one value for the element/variable word的元素,这样生成的数组是:

Array ( [0] => stdClass Object ( [word] => alpha [sentence] => A is the first letter in the word Alpha. ) [1] => stdClass Object ( [word] => beta [sentence] => B is the first letter in the word Beta. ) )

The question is that what is messing it up and what can I do to fix it?问题是什么把它搞砸了,我能做些什么来解决它?

<?php 

$objectOne = new stdClass;
$objectOne->word = 'alpha';
$objectOne->sentence = 'A is the first letter in the word Alpha.';

$objectTwo = new stdClass;
$objectTwo->word = 'beta';
$objectTwo->sentence = 'B is the first letter in the word Beta.';

$objectThree = new stdClass;
$objectThree->word = 'Select one';
$objectThree->sentence = '';

$items = array($objectOne, $objectTwo, $objectThree, $objectThree, $objectThree, $objectThree );


print_r($items);//check
echo '<br><br>count($items) >> '.count($items).'<br><br>';//check


for ($a=0; $a < count($items); $a++) {
    echo '<br><br>We are entering index '.$a.'<br><br>';//check
    echo '<br>'.$items[$a]->word.'<br>';//check

    if ( ($items[$a]->word)=="Select one"  ) {
        echo '<br>YES if ( ($items['.$a.']->word)=="Select one"  ) AT '.$a.' INDEX.<br>';//check
        unset($items[$a]);
        /**/array_splice($items, $a, 1);
    }

    echo '<br><br>We are leaving index '.$a.'<br><br>';//check
}


echo '<br><br>AFTER:-<br>';//check
print_r($items);//check

?>

OUTPUT:输出:

Array ( [0] => stdClass Object ( [word] => alpha [sentence] => A is the first letter in the word Alpha. ) [1] => stdClass Object ( [word] => beta [sentence] => B is the first letter in the word Beta. ) [2] => stdClass Object ( [word] => Select one [sentence] => ) [3] => stdClass Object ( [word] => Select one [sentence] => ) [4] => stdClass Object ( [word] => Select one [sentence] => ) [5] => stdClass Object ( [word] => Select one [sentence] => ) )

count($items) >> 6



We are entering index 0


alpha


We are leaving index 0



We are entering index 1


beta


We are leaving index 1



We are entering index 2


Select one

YES if ( ($items[2]->word)=="Select one" ) AT 2 INDEX.


We are leaving index 2



We are entering index 3


Select one

YES if ( ($items[3]->word)=="Select one" ) AT 3 INDEX.


We are leaving index 3



AFTER:-
Array ( [0] => stdClass Object ( [word] => alpha [sentence] => A is the first letter in the word Alpha. ) [1] => stdClass Object ( [word] => beta [sentence] => B is the first letter in the word Beta. ) [2] => stdClass Object ( [word] => Select one [sentence] => ) ) 

Use a temp variable for iteration as you unset the key of main during the for execution.在 for 执行期间取消设置 main 的键时,使用temp变量进行迭代。 Maybe, this should work :-也许,这应该有效:-

$temp = $items;
for ($a=0; $a < count($temp); $a++) {
  echo '<br><br>We are entering index '.$a.'<br><br>';//check
  echo '<br>'.$items[$a]->word.'<br>';//check

  if ( ($items[$a]->word)=="Select one"  ) {
      echo '<br>YES if ( ($items['.$a.']->word)=="Select one"  ) AT '.$a.' INDEX.<br>';//check
      unset($items[$a]);
      /**/array_splice($items, $a, 1);
  }

  echo '<br><br>We are leaving index '.$a.'<br><br>';//check
}

The condition is not always true.条件并不总是正确的。 The condition in your for loop recalculates the size of the array in each iteration. for 循环中的条件在每次迭代中重新计算数组的大小。 The length of the array changes whenever an item is removed.每当删除项目时,数组的长度就会发生变化。

The value of $a and count($items) each time the condition is checked is as follows:每次检查条件时$acount($items)的值如下:

$a | count($items) | $a < count($items)
---------------------------------------
 0 | 6             | true 
 1 | 6             | true
 2 | 6             | true
 3 | 5             | true  -- $items[2] was removed
 4 | 4             | false -- $items[3] was removed

You should store the size of the array in a variable and use that instead.您应该将数组的大小存储在变量中并使用它。 Also since array_splice doesn't preserve numeric keys you will eventually get an undefined offset notice when trying to access $items[4] and $items[5] .此外,由于array_splice不保留数字键,您最终会在尝试访问$items[4]$items[5]时收到未定义的偏移通知。 That line is not required.那条线不是必需的。

$count = count($items);
for ($a=0; $a < $count; $a++) {

Better yet you can use a foreach instead of the for and use $item instead of $items[$a] :更好的是,您可以使用foreach代替for并使用$item代替$items[$a]

foreach ($items as $a=>$item) {
    echo '<br><br>We are entering index '.$a.'<br><br>';//check
    echo '<br>'.$item->word.'<br>';//check
    ...
    unset($items[$a]); //can't use $item because it is a copy and not a reference

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM