[JavaScript][TypeScript] 配列の直積(すべての順列)を得る関数productを作る

はじめに

JavaScript/TypeScriptで複数の配列の直積(すべての順列)が欲しいという場面があった。

Pythonなら組み込み関数productで解決できるのだが、JavaScript/TypeScriptではそのような関数を見つけられなかったので、自作してみることにした。

Pythonの場合

Pythonでは、標準ライブラリitertoolsのproduct関数を使うと、複数の配列の直積を得ることができる。

返り値はイテレータなので、リストに変換して表示させれば、目的の配列が得られていることが分かる。

gist.github.com
出力結果

[(1, 4), (1, 5), (2, 4), (2, 5), (3, 4), (3, 5)]

product関数を使えば、単純に配列の直積(順列)を得ることもできるし、複数のfor文を一つに減らしてコードの見通しを良くすることもできる。

cyanatlas.hatenablog.com

TypeScriptで書く

引数となる配列の数が分からないため、ここでは再帰を使って書くことにした。

大きな配列を代入する場合はメモリに注意されたい。

gist.github.com

上のコードをutils.tsというファイル名で保存し、同じディレクトリで次のコードを実行すると、目的の配列が得られていることが確認できる。

gist.github.com
出力結果

[ [ 1, 4 ], [ 1, 5 ], [ 2, 4 ], [ 2, 5 ], [ 3, 4 ], [ 3, 5 ] ]

JavaScriptの場合

上のコードをコンパイルしたもの

gist.github.com

まとめ

  • JavaScript/TypeScriptでもPythonで提供されているような直積を求める関数productを書くことができた。
  • 引数となる配列の数が不明なため、再帰を使って書いた。
  • ここでは引数を二次元配列としたが、残余引数構文を使った書き方もありそう。
  • 使用する際は、組み合わせ爆発や再帰処理に伴うメモリ不足に注意が必要。