PHP入門:Generatorsについて -vol.4-

スポンサーリンク
PHP入門:Generatorsについて -vol.4- 用語解説
PHP入門:Generatorsについて -vol.4-
この記事は約6分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、PHPのGeneratorsについてご紹介します。

スポンサーリンク

背景

PHP8.2を利用したAPIを開発しているときにGeneratorsを利用したので、そのときの調査内容を備忘としてのこしました。

こちらのサイトを参考にしています。

yield fromによるジェネレータの委譲

ジェネレータの委譲を使用すると、別のジェネレータ、Traversableオブジェクト、または配列から値をyieldできます。yield fromキーワードを使用します。外側のジェネレータは、内側のジェネレータ、オブジェクト、または配列からすべての値をyieldします。これが無効になるまで、その後外側のジェネレータで実行が続行されます。

ジェネレータがyield fromと組み合わされる場合、yield from式は内部ジェネレータによって返される値も返します。

注意

yield fromを使って配列に格納する場合(例えば、iterator_to_array()を使用する場合)、キーはリセットされません。yield fromは、Traversableオブジェクトや配列が返すキーを保持します。そのため、一部の値は別のyieldまたはyield fromと共通のキーを共有する可能性があります。これらの値を配列に挿入すると、同じキーの以前の値が上書きされることになります。

この問題が影響する一般的なケースは、iterator_to_array()がデフォルトでキー付きの配列を返す場合です。これは予期しない結果を引き起こす可能性があります。iterator_to_array()には第二のパラメータpreserve_keysがあり、これをfalseに設定することで、Generatorが返すキーを無視してすべての値を収集できます。

サンプル1

<?php
function inner() {
    yield 1; // key 0
    yield 2; // key 1
    yield 3; // key 2
}
function gen() {
    yield 0; // key 0
    yield from inner(); // keys 0-2
    yield 4; // key 1
}
// pass false as second parameter to get an array [0, 1, 2, 3, 4]
var_dump(iterator_to_array(gen()));

このコードは、PHPジェネレータを使用する例です。ジェネレータは、特定の条件で値を生成するための強力な機能です。

  1. ジェネレータ関数の定義:
    • gen というジェネレータ関数が定義されています。
    • この関数は、yield 0; でキー0の値を返します。
    • yield from inner(); で内部のジェネレータ関数 inner() からキー0から2までの値を受け取ります。
    • yield 4; でキー1の値を返します。
  2. ジェネレータの利用:
    • iterator_to_array(gen()) を使って、ジェネレータから値を配列に変換します。
    • 第二のパラメータとして false を渡すことで、キーをリセットせずにすべての値を収集します。
  3. 出力結果:
    • 上記のコードを実行すると、以下のような出力が得られます:
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(4)
  [2]=>
  int(3)
}

サンプル2

<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    yield 9;
    yield 10;
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

foreach (count_to_ten() as $num) {
    echo "$num ";
}

このコードは、PHPジェネレータを使用する例です。ジェネレータは、特定の条件で値を生成するための強力な機能です。

  1. ジェネレータ関数の定義:
    • count_to_ten というジェネレータ関数が定義されています。
    • この関数は、以下の値を順番に生成します:
      • 1
      • 2
      • 配列 [3, 4] の要素
      • ArrayIterator([5, 6]) の要素
      • seven_eight() 関数からの値
      • 9
      • 10
  2. ジェネレータの利用:
    • foreach (count_to_ten() as $num) を使って、ジェネレータから値を取り出します。
    • 各値は $num に代入され、スペースで区切って表示されます。
  3. 出力結果:
    • 上記のコードを実行すると、以下のような出力が得られます:
1 2 3 4 5 6 7 8 9 10

サンプル3

<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    return yield from nine_ten();
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

function nine_ten() {
    yield 9;
    return 10;
}

$gen = count_to_ten();
foreach ($gen as $num) {
    echo "$num ";
}
echo $gen->getReturn();

このコードは、PHPジェネレータを使用する例です。ジェネレータは、特定の条件で値を生成するための強力な機能です。

  1. ジェネレータ関数の定義:
    • count_to_ten というジェネレータ関数が定義されています。
    • この関数は、以下の値を順番に生成します:
      • 1
      • 2
      • 配列 [3, 4] の要素
      • ArrayIterator([5, 6]) の要素
      • seven_eight() 関数からの値
      • 9
      • 10
  2. ジェネレータの利用:
    • foreach ($gen as $num) を使って、ジェネレータから値を取り出します。
    • 各値は $num に代入され、スペースで区切って表示されます。
  3. 出力結果:
    • 上記のコードを実行すると、以下のような出力が得られます:
1 2 3 4 5 6 7 8 9 10

おわりに

今日は、PHPのGeneratorsについてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました