for
ループで、次のことを行う方法について聞いたことがあるでしょう。
_for ($i = 0, $count = count($array); $i < $c; ++$i)
{
// Do stuff while traversing array
}
_
これの代わりに:
_for ($i = 0; $i < count($array); ++$i)
{
// Do stuff while traversing array
}
_
パフォーマンス上の理由から(つまり、_$count
_を初期化すると、条件付きチェックごとにcount()
を呼び出すのではなく、count()
を1回だけ呼び出すことになります)。
foreach
ループで次のようにすると、違いが生じますか?
_$array = do_something_that_returns_an_array();
foreach ($array as $key => $val)
{
// Do stuff while traversing array
}
_
これの代わりに:
_foreach (do_something_that_returns_an_array() as $key => $val)
{
// Do stuff while traversing array
}
_
状況が私にどちらかを使用することを許可すると仮定しますか?つまり、PHPは、どちらの場合も1回だけ関数を呼び出すのですか、それとも2番目のケースが関数を何度も呼び出すfor
のようなものですか?
foreach()
is イテレータを使用して実装 -したがって、配列を1回返す関数を呼び出すだけで、既存の結果セットを指すイテレータを使用して各項目を続行します。
それをテストすることは確かにそれに答えると思います。
これが私のコードです:
function GetArray() {
echo "I am called.\n";
return array("One"=>1, "Two"=>2, "Three"=>3, "Four"=>4, "Five"=>5);
}
echo "Case #1\n";
$array = GetArray();
foreach ($array as $key => $val){
// Do stuff while traversing array
echo " Inside the loop: $key => $val\n";
}
echo "\n";
echo "Case #2\n";
foreach (GetArray() as $key => $val) {
// Do stuff while traversing array
echo " Inside the loop: $key => $val\n";
}
echo "\n";
結果は次のとおりです。
ケース#1 呼び出されました。 ループ内:1 => 1 ループ内:2 => 2 ループ内ループ:3 => 3 ループ内:4 => 4 ループ内:5 => 5 ケース#2 私は呼ばれています。 ループの内側:1 => 1 ループの内側:2 => 2 ループの内側:3 => 3 ループ:4 => 4 ループの内側:5 => 5
どちらも呼び出し関数を1回読み取ります。だから違いはありません。
foreach
は入力配列のコピーを作成し、各反復でそれを処理します。したがって、foreach (do_something_that_returns_an_array() as $key => $val)
を使用すると、do_something_that_returns_an_array()
が1回だけ呼び出されます。
何が起こるかを見るために例を設定します。何かのようなもの...
function do_something_that_returns_an_array() {
echo 'I have been called!';
return array('i am an', 'array');
}
do_something_that_returns_an_array()
は、forループとは異なり、複数回実行する理由がないため、1回だけ実行されると常に想定してきました。 forループの真理チェッカーがすべての反復の最後に実行される理由は、非常に複雑なチェッカーを許可するためです。
テストとして、私は次のことを行いました。
_function get_array() {echo 5; return array(1,2,3,4,5);}
foreach(get_array() as $key => $value) {}
_
スクリプトは5回印刷しました。したがって、関数get_array()
は1回だけ評価します。
foreach()は、IteratorまたはIteratorAggregateオブジェクト(たとえば、インターフェイスを実装する配列やオブジェクト)で機能します。 immutableオブジェクトでは機能しません。関数は不変オブジェクトを返すため、返す配列は、foreachする前にIteratorオブジェクトにコピーする必要があります(php自体によって作成されます)