ardggy's blog

Esc - Meta - Alt - Ctrl - Shift

複数のイテレータを合流させる(承前)

前は2つのイテレータを合流させるパターンを書いたが、3つ以上のイテレータも混ぜられないだろうか。 confluence(confluence($it1, $it2, $compare), $it3, $compare) とやれば複数混ぜられそうな気がする。

つまり畳み込みの計算で、array_reduce をつかえばいい。

<?php
declare(strict_types=1);

// x=0: 0, 3, 6, 9, ...
// x=1: 1, 4, 7, 10, ...
// x=2: 2, 5, 8, 11, ...
function mod3($x = 0): Iterator {
  for ($y = $x; 1; $y += 3) { yield $y; }
}

$compare = fn($x, $y) => $x <=> $y;
$iter3 = array_reduce([mod3(0), mod3(1), mod3(2)],
                      fn($acc, $it) => confluence($acc, $it, $compare),
                      $initial = new EmptyIterator);

assert([0,1,2,3,4,5,6,7,8,9] === iterator_to_array(new LimitIterator($iter, 0, 10)));

array_reduce は左からの畳込みだけど、右から畳み込んでも動くんじゃないかと思う。