2011-02-09 2 views
1

これは奇妙な質問ですが、面白いので私は尋ねると思っていました。私はPHPのforeachループがどのように動作するのが好きではないと私はいつも私がしたすべての形式でそれを使用し、foreachループの内側にカウンタを追加し、最後の要素にいるかどうかを知るために使用します。アーキテクチャを変更することはできますか?

$counter = 1; 
$array_size = count($array); 
foreach($array as $item){ 
    //code 
    if($counter == $array_size){ 
     $isLast = true 
    } else { 
     $isLast = false; 
    } 
    $counter++; 
} 

私の質問は:私はを必要とせずに、上書きまたはフォークまたは継承(またはあなたがそれを呼び出すために好きな)私は今、これを行うことができるように、この新しい機能が含まれるように、元のPHPのforeachループをすることができますカウンタなどを初期化する。

newforeach($array as $item){ 
    //code 
    $isLast = //something that returns true/false; 
} 

それは面白いアイデアだので、ここハードコアPHPの選手の一人が何らかの形でこれを可能にすることができる場合、私は疑問に思いますか?または言語自体をハッキングすることなく複雑すぎるこの種の修正方法?

+2

、確実に、言語の制御構造の動作方法を変更すると、言語をハッキング」が必要です自分自身 " –

+0

[あなたの他の質問](http://stackoverflow.com/questions/4943719/in-foreach-islastitem-exists)についてはどうですか? – Gumbo

+1

少なくとも、$ isLast =($ counter == $ array_size); ' – gnur

答えて

1

をあなたの質問は、単に「あなたは、PHPの言語構造の実装をオーバーライドすることができます」答えはノーであるされている場合。これは、JavascriptやRubyと呼ばれることも多いMonkey PatchingやDuck Punchingのような他の動的ランゲージの特徴です。

あなたはwhileループにあなたのforeachを書き換えると)(次を使用してアイテムを反復処理し、そのような可能性が
2

これは奇妙なことです。なぜそうでないのですか?

$isLast = FALSE; 
foreach($array as $count => $item) 
{ 
    $isLast = ($count+1 == count($array)) 
} 

私はPHPを書いて以来、他の誰かがそのコードを整理できると確信しています。あなたはそれを行うのあなたの方法を好きなら

あるいは、なぜ単に入れないで、あなたのIF/THEN/ELSE関数にはisLastを言うと、そのようにそれを呼び出す場合:

$isLast = isLast($item, $array)

+1

前の質問でzmolの問題にいくつかの解決策があります - http://stackoverflow.com/questions/4943719/in-foreach-islastitem-exists - あなたは連想配列、またはキー配列がない配列では機能しません。 (おそらくソートの後に)シーケンシャル(おそらくソート後)で、項目がなくなっていない(セットされていないか類似していない) –

+0

@マーク・ベイカー:シーケンシャル・キーの良い点。私は連想配列で作業していないと思っていました。彼自身が鍵を使わなかったので見ています。彼の以前の質問を見なかったことを謝ります。 – sevenseacat

+0

お詫び申し上げます...私はちょうどシーケンシャルオンリーシンドロームに苦しんでいない多くの代替ソリューションを指摘していました –

0

あなたはそれを行うことができます(構文を変更せずに): - 特に限り、あなたはちょうどだとして

function foreach_counter($ar, $callback) { 
    $counter = 1; 
    $array_size = count($ar); 
    foreach($ar as $item){ 
    $callback($item, $counter, $counter == $array_size); 
    $counter++; 
    } 
} 

foreach_counter(array('a','b'), function($item, $counter, $isLast) { 
    echo $counter . ': ' . $item . '' . ($isLast ? 'END' : ','); 
}); 
// outputs 1: a, 2: b END 

しかし、あなたが見ることができるように、それはあなたがすることができますがので、あなたがそれを行うべきではない、簡潔なバージョンを読み取ることが難しくなりますPHPを理解し始めた。

多くの場合、このようなループで文字列を作成したいとします。そのためimplodeを使用します。

echo implode(', ', array(1,2,3)); 
// output: 1, 2, 3 
4

あなたがあなたのために、このチェックを実行するにisLast()メソッドを使用すると、(あなたはそれがIterator interfaceを実装持っている必要があります)反復処理している配列をラップするクラスを書くことができます。

このような何か(擬似コード):

$arrayIterator = new MyArrayIterator($myArray); 

foreach ($arrayIterator as $item) 
{ 
    if ($arrayIterator->isLast()) 
    { 
    doStuff(); 
    } 
} 
+1

[CachingIteratorには 'hasNext'メソッドがあります(http://stackoverflow.com/questions/4804599/add-a-char-to-all-array-items-ap-art-last-for-for-foreach/4804812#4804812)、 'ArrayIterator'を単にその中にラップすることができます。しかし、反復子を示唆する+1。 – Gordon

1

:定義により

$array = array('a' => 'hi', 2 => 2515, 'as' => 'foo'); 
while (true) { 
    $item = current($array); 
    echo $item, "\n"; 
    if (!next($array)) { 
     echo '^last item!'; 
     break; 
    } 
} 
関連する問題