// 前
[
[0, 1, 2],
[3, 4, 5],
]
↓
// 後
[
[0, 3],
[1, 4],
[2, 5],
]
これは需要がある!…………のか?
ということで複数の配列を同期して回転させるIterator.zipの紹介です。
Joint Iteration
複数のイテレータの進行を同期させる提案。
現在のステージは2.7です。
motivation
2つ以上のイテレータがあり、対応する値に応じてまとめて操作したい場合があります。
この問題に対する一般的な解決策はイテレータの結合であり、zipと呼ばれます。
presentations to committee
・2024/06のプレゼン資料
・2024/01のプレゼン資料
・2023/11のプレゼン資料
・2023/09のプレゼン資料
proposal
2つのメソッドIterator.zip・Iterator.zipKeyedが追加されます。
zipは反復可能オブジェクトの反復可能オブジェクトを受け取り、渡された反復可能オブジェクトの位置に対応する位置を持つ配列の反復可能オブジェクトを生成します。
zipKeyedは値が反復可能オブジェクトであるオブジェクトを受け取り、渡されたオブジェクトのキーに対応する位置を持つオブジェクトの反復可能オブジェクトを生成します。
Iterator.zip([
[0, 1, 2],
[3, 4, 5],
]).toArray()
/*
[
[0, 3],
[1, 4],
[2, 5],
]
*/
Iterator.zipKeyed({
a: [0, 1, 2],
b: [3, 4, 5, 6],
c: [7, 8, 9],
}).toArray()
/*
[
{ a: 0, b: 3, c: 7 },
{ a: 1, b: 4, c: 8 },
{ a: 2, b: 5, c: 9 },
]
*/
いずれも第二引数にオプションを受け取ります。
オプションmodeはshortest・longest・strictを指定可能です。
Iterator.zipKeyed({
a: [0, 1, 2],
b: [3, 4, 5, 6],
c: [7, 8, 9],
}, {
mode: 'longest',
padding: { c: 10 },
}).toArray()
/*
[
{ a: 0, b: 3, c: 7 },
{ a: 1, b: 4, c: 8 },
{ a: 2, b: 5, c: 9 },
{ a: undefined, b: 6, c: 10 },
];
*/
considered design space
考慮事項。
イテレータはふたつだけサポートするのか。
それともそれ以外の何か?
決定:0以上全て。
イテレータは配列の位置指定で渡すべきか。
オブジェクトの名前指定で渡すべきか。
決定:両方、別のAPIで対応した。
イテレータは可変長引数で受け取るか、Iterable/objectで受け取るか。
決定:Iterable/object
可変長引数だとオプションを渡せなくなるため。
Iterator.fromやflatMapなどもサポートするか。
決定:反復可能オブジェクトだけに限定。
イテレータが終わったら、残ったイテレータはどうする?
決定:引数modeによって異なる。
tupple以外の方法で値を結合するバリアントがほしい。
決定:このproposalでは対象外。
zipLongest・zipFilled・zipAllもほしい。
決定:オプションで対応。
数が異なる際にエラーを出すzipEqual・zipStrictもほしい。
決定:オプションで対応。
感想
うっかりIterator.zipをアドレス欄に入れたらアクセスできてしまって驚いたよ。
JavaScriptがStage4になったらプルリクを投げてあげてね。
正直個人的には、この手の関数の使い道がよくわからないんですよね。
サンプルとして挙げられがちな[["佐藤","鈴木","田中"],[10,20,30]]みたいなのは最初からまとめとけよって思いますし。
しかしIterator.zipにもあるように各種言語でそれなりに実装されていて(もちろんPHPにもある)、そして今回JavaScriptでも実装されるということは、たしかな需要が存在するということでしょう。
こんなときに使うんだってのがあったらぜひ教えてくださいな。