2012-05-05 5 views
3
$animals = array('cat', 'dog', 'horse', 'elephant'); 
foreach($animals as $animal) 
{ 
    var_dump($animal); 
    next($animals); 
} 

上記のコードは、cat、dog、horse、elephantの出力です。私はnext関数が$animalsの内部ポインタを動かすべきだと思ったので、代わりにこの出力を得るべきです:cat、horse。PHP:どのようにforeachループ内の配列ポインタを移動するには?

$ animalsの内部ポインタをforeachの影響を受けるように前方(後方)に移動させるにはどうすればよいですか?

EDIT 1:

マニュアルから:

foreachの内部配列ポインタに依存しているよう ループ内でそれを変更すると、予期しない動作につながる可能性があります。

それでも、これは私がする必要があると思います。

EDIT 2:

「常識」のリンクあたり、私は私の問題のより詳細な説明を提供します。

array $foos; 

start loop of $foos 
- do thing #1 
- do thing #2 
- do thing #3 
- keep doing thing #3 while the current value of $foos in the loop meets a certain criteria 
loop 

実行がループの最初に戻るときは、#3で最後にアクセスされた配列から続行する必要があります。 配列はアソシエートであるため、for ($i = 0 ...のアプローチは機能しません。

+3

への参照これは実際の仕事の説明ではなく、同じxyの問題です。なぜあなたはそれを必要としますか? –

+2

おそらく、この実装のどこかに隠れた、よりクリーンなデザインがあります。 –

答えて

8

:あなたはより多くの何も必要ありません。

それはイテレータであるとして、あなたは、その上にいくつかの初歩的な例反復ながら、あなたは位置を変更することができます:それはあなたが箱の外に必要なすべてを提供する必要があります

foreach ($iterator as $current) { 
    $iterator->next(); 
} 

を。そうでない場合は、を自分でIterator­Docsにカプセル化することもできます。

6

foreachにダイレクトポインタアクセスを使用しないでください。配列内を移動したい場合は、foreachをCスタイルのforに置き換えてください。これは一番上の方が細いですが、foreachの場合と同じループ本体で動作しますが、内部ポインタを使用して目的の結果が得られるという違いがあります。

$animals = array('cat', 'dog', 'horse', 'elephant'); 
for ($animal = current($animals), $index = key($animals); 
     $animal; 
     $animal = next($animals), $index = key($animals)) { 
    print "$index:"; 
    var_dump($animal); 
    next($animals); 
} 

出力:

0:string(3) "cat" 
2:string(5) "horse" 

それはあなたが実際には配列内で前後に動き回っているときforeachのように構築ストレートの繰り返しを使用することは非常に誤解を招きやすいです。上記のforループはこの点では優れていますが、多くはそうではありません。ループの本体に明示的にすべての詳細が記載されたwhileループが最適な選択肢になります。

+0

Mark、私は何をしようとしているのか少し説明するためにオリジナルの質問を更新しました。それが役に立てば幸い。 – StackOverflowNewbie

+0

上記のfor()ループは、配列全体のforeach()ループとまったく同じように動作します。あなたが '' $ key => $ value'を実行しているならば、今まで行ってきた 'key'への呼び出しを追加するだけです。 –

+0

私はあなたのfor-loopの2番目のパラメータで少し混乱しています。それは有効な構文ですか? – StackOverflowNewbie

-1

foreachループの最後で手動でポインタを増やす必要はありません。自動的に行われます。あなただけのseekable­DocsあるArrayIterator­Docsを作成することができます

foreach($animals as $animal) { 
    var_dump($animal) 
} 
+0

OPは要素@andrewsiをスキップしようとしています。 –

+0

私は知っていますが、私は本当に次の項目へのポインタを進めたいと思います。元の投稿で期待している出力例を参照してください。 – StackOverflowNewbie

+0

下記の更新された回答をご覧ください:@StackOverflowNewbie。 –

4

Markの解はかなり近いですが、配列に0、false、または2番目のforループ式でfalseを評価する値が含まれていると失敗します。

この解決策はすべての配列で機能し、forループの "精神"に少し近いです。最初のループ式のreset()は、foreachの場合と同様に、配列の先頭から確実に開始します。 forループの2番目の式は、配列ポインタが指す要素が存在するかどうかを評価する必要があります。 key()は、配列のポインタが配列の終わりを指している場合、または配列が空の場合はnullを返します。 3番目の式は、各繰り返しの最後に配列ポインタを進めます。

$animals = array('cat', 'dog', 'horse', 'elephant'); 
for (reset($animals); key($animals) !== null; next($animals)) { 
    $animal = current($animals); 
    var_dump($animal); 
    next($animals); 
} 

この出力:

string(3) "cat" 
string(5) "horse" 
+0

実際にはforループのように見え、多くの状況で使用でき、問題を解決します。ありがとうございました。 – Noumenon

0

私は彼がただの要素をスキップしたい原因、彼はforeachの内側のif句と組み合わせて「続ける」を使用することができると思います。

$skip=array ('dog', 'elephant'); 
$animals = array('cat', 'dog', 'horse', 'elephant'); 
foreach($animals as $animal) 
{ 
    if (in_array($animal, $skip)) { 
     continue; 
    } 
    var_dump($animal); 
} 

この意志出力:

string(3) "cat" 
string(5) "horse" 

Variante 2なしでは同じ効果を続行:

$skip=array ('dog', 'elephant'); 
$animals = array('cat', 'dog', 'horse', 'elephant'); 
foreach($animals as $animal) 
{ 
    if (!in_array($animal, $skip)) { 
     var_dump($animal); 
    } 

} 
0

foreach ($variable as $key => &$value) { 

} 

$valueの評価に&を追加$variable[$key]アドレス

関連する問題