PHP
配列の繰り返し
サーチ…
構文
- for($ i = 0; $ i <count($ array); $ i ++){incremental_iteration(); }
- for($ i = count($ array)-1; $ i> = 0; $ i--){reverse_iteration(); }
- foreach($ data as $ datum){}
- foreach($ data => $ datum){}
- foreach($ data as $ datum){}
備考
配列を反復するメソッドの比較
方法 | 利点 |
---|---|
foreach | 配列を反復する最も簡単な方法です。 |
foreach 参照 | 配列の要素を反復して変更する簡単な方法。 |
for インクリメンタルインデックス付き | 空のシーケンスで配列を反復できるようにします。たとえば、複数の要素をスキップまたは反転する |
内部配列ポインタ | ループを使用する必要はなくなりました(関数呼び出し、シグナル受信などのたびに1回反復できるようになりました) |
複数の配列をまとめて反復する
時には同じ長さの2つの配列を繰り返し処理する必要があります。
$people = ['Tim', 'Tony', 'Turanga'];
$foods = ['chicken', 'beef', 'slurm'];
array_map
はこれを実現する最も簡単な方法です:
array_map(function($person, $food) {
return "$person likes $food\n";
}, $people, $foods);
出力される:
Tim likes chicken
Tony likes beef
Turanga likes slurm
これは、共通の索引を使用して行うことができます。
assert(count($people) === count($foods));
for ($i = 0; $i < count($people); $i++) {
echo "$people[$i] likes $foods[$i]\n";
}
2つの配列にインクリメンタルキーがない場合は、 array_values($array)[$i]
を使用して$array[$i]
を置き換えることができます。
両方の配列のキーの順序が同じ場合、配列の1つにforeach-with-keyループを使用することもできます。
foreach ($people as $index => $person) {
$food = $foods[$index];
echo "$person likes $food\n";
}
別々の配列は、同じ長さで同じキー名を持つ場合にのみループスルーできます。つまり、キーを指定せずに番号が付けられていれば、あなたはうまくいきます。あるいは、キーに名前を付けて、それぞれの配列に同じ順序でキーを付けるとします。
また、 array_combine
使用することもできarray_combine
。
$combinedArray = array_combine($people, $foods);
// $combinedArray = ['Tim' => 'chicken', 'Tony' => 'beef', 'Turanga' => 'slurm'];
前と同じようにすることで、これをループすることができます:
foreach ($combinedArray as $person => $meal) {
echo "$person likes $meal\n";
}
インクリメンタルインデックスの使用
このメソッドは、0から配列内の最大のインデックスまで整数をインクリメントすることによって機能します。
$colors = ['red', 'yellow', 'blue', 'green'];
for ($i = 0; $i < count($colors); $i++) {
echo 'I am the color ' . $colors[$i] . '<br>';
}
これにより、 array_reverse
を使用せずに配列を逆順に反復することも可能になり、配列が大きい場合にオーバーヘッドが発生する可能性があります。
$colors = ['red', 'yellow', 'blue', 'green'];
for ($i = count($colors) - 1; $i >= 0; $i--) {
echo 'I am the color ' . $colors[$i] . '<br>';
}
この方法を使用すると、インデックスを簡単にスキップまたは巻き戻すことができます。
$array = ["alpha", "beta", "gamma", "delta", "epsilon"];
for ($i = 0; $i < count($array); $i++) {
echo $array[$i], PHP_EOL;
if ($array[$i] === "gamma") {
$array[$i] = "zeta";
$i -= 2;
} elseif ($array[$i] === "zeta") {
$i++;
}
}
出力:
alpha
beta
gamma
beta
zeta
epsilon
インクリメンタルインデックスを持たない配列(逆順のインデックスを持つ配列を含みます。例えば[1 => "foo", 0 => "bar"]
、 ["foo" => "f", "bar" => "b"]
)、これは直接行うことはできません。 array_values
またはarray_keys
代わりに使用することができます。
$array = ["a" => "alpha", "b" => "beta", "c" => "gamma", "d" => "delta"];
$keys = array_keys($array);
for ($i = 0; $i < count($array); $i++) {
$key = $keys[$i];
$value = $array[$key];
echo "$value is $key\n";
}
内部配列ポインタの使用
各配列インスタンスには内部ポインタが含まれています。このポインタを操作することにより、配列の異なる要素を同じ呼び出しから別々の時間に取得することができます。
each
を使用each
each()
呼び出すeach()
に、現在の配列要素のキーと値が返され、内部の配列ポインタがインクリメントされます。
$array = ["f" => "foo", "b" => "bar"];
while (list($key, $value) = each($array)) {
echo "$value begins with $key";
}
next
使用
$array = ["Alpha", "Beta", "Gamma", "Delta"];
while (($value = next($array)) !== false) {
echo "$value\n";
}
この例では、配列内のどの要素もboolean false
と同一ではないことを前提としていfalse
。このような仮定を避けるには、内部ポインタが配列の終わりに達しているかどうかを調べるためにkey
を使用しkey
。
$array = ["Alpha", "Beta", "Gamma", "Delta"];
while (key($array) !== null) {
echo current($array) . PHP_EOL;
next($array);
}
これはまた、直接ループを持たない配列の繰り返しを容易にします:
class ColorPicker {
private $colors = ["#FF0064", "#0064FF", "#64FF00", "#FF6400", "#00FF64", "#6400FF"];
public function nextColor() : string {
$result = next($colors);
// if end of array reached
if (key($colors) === null) {
reset($colors);
}
return $result;
}
}
foreachの使用
ダイレクトループ
foreach ($colors as $color) {
echo "I am the color $color<br>";
}
キー付きループ
$foods = ['healthy' => 'Apples', 'bad' => 'Ice Cream'];
foreach ($foods as $key => $food) {
echo "Eating $food is $key";
}
リファレンスによるループ
上記の例のforeach
ループでは、値( $color
または$food
)を直接変更しても配列内の値は変更されません。 &
演算子は、値が配列内の要素への参照ポインタになるように指定する必要があります。
$years = [2001, 2002, 3, 4];
foreach ($years as &$year) {
if ($year < 2000) $year += 2000;
}
これは、次のようになります。
$years = [2001, 2002, 3, 4];
for($i = 0; $i < count($years); $i++) { // these two lines
$year = &$years[$i]; // are changed to foreach by reference
if($year < 2000) $year += 2000;
}
並行性
PHP配列は、反復処理中に並行処理の問題(Java List
とは異なります)を行うことなく、どのような方法でも変更できます。配列が参照によって反復される場合、後で反復は配列への変更の影響を受けます。そうしないと、配列の変更はそれ以降の反復には影響しません(代わりに、配列のコピーを反復処理しているかのように)。値によるルーピングの比較:
$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => $value) {
if ($key === 0) {
$array[6] = 17;
unset($array[4]);
}
echo "$key => $value\n";
}
出力:
0 => 1
2 => 3
4 => 5
6 => 7
しかし、配列が参照で反復される場合、
$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => &$value) {
if ($key === 0) {
$array[6] = 17;
unset($array[4]);
}
echo "$key => $value\n";
}
出力:
0 => 1
2 => 3
6 => 17
4 => 5
のキー値セットはもはや反復されず、 6 => 7
は6 => 17
変更されます。
ArrayObjectイテレータの使用
Php配列セレクタを使用すると、配列やオブジェクトを反復処理しながら値を変更したり設定解除したりすることができます。
例:
$array = ['1' => 'apple', '2' => 'banana', '3' => 'cherry'];
$arrayObject = new ArrayObject($array);
$iterator = $arrayObject->getIterator();
for($iterator; $iterator->valid(); $iterator->next()) {
echo $iterator->key() . ' => ' . $iterator->current() . "</br>";
}
出力:
1 => apple
2 => banana
3 => cherry