2

次の SSCCE では、ループが3 を超えforて実行されないのはなぜですか。条件は5 になるまでループを実行できるようにする必要があります。$a$a

そして、最後のステートメントの出力はさらに奇妙です。

私が達成しようとしているのは、結果の配列が次のようになるようにSelect one、 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. ) )

問題は、何がそれを台無しにしていて、それを修正するために何ができるかということです.

<?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

?>

出力:

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] => ) ) 
4

2 に答える 2

1

temp実行中にメインのキーを設定解除するため、反復用の変数を使用します。多分、これはうまくいくはずです:-

$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
}
于 2015-11-10T07:23:35.510 に答える
1

The condition is not always true. The condition in your for loop recalculates the size of the array in each iteration. 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:

$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]. 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 ($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
于 2015-11-10T07:28:23.907 に答える