3
1

[JavaScript] ライブラリなしで配列操作の遅延評価ができる(予定)

Last updated at Posted at 2024-09-30

JavaScriptの言語仕様に新しく追加される予定の「Iterator Helpers」について解説します。

Iterator Helpers Proposalについて

JavaScriptの言語仕様に、イテレータを操作するための便利なメソッドを追加しようという提案です。
2024年9月現在Stage3であり、今のところまだ全てのブラウザやランタイムで利用できるわけではありません。

この機能を使うと、配列操作を遅延評価することができます。

配列操作の遅延評価とは

従来のJavaScriptの配列操作関数では、メソッドを呼び出した瞬間に配列操作が走っていました。

従来の配列操作
// .map()を呼び出すと、即時関数で渡した関数がすぐに実行され、結果の配列が作成される
const result = [0, 1, 2]
    .map(val => val + 1)
    .map(val => val ** 2);

一方、計算処理をすぐに行い結果の配列を先に生成するのではなく、実際に結果が必要になる時まで計算処理が延期させることを、遅延評価といいます。

JavaScriptでライブラリを使わずに遅延評価する

こちらのメソッドは2024年9月現在、Chrome、Node.js、Deno、FirefoxのTechnology Preview版で利用できます。Safariではまだ利用できません。

配列に対して.values()メソッドを使うとIteratorオブジェクトに変換できます。
このIteratorオブジェクトに対して.map()などのメソッドを使うと、遅延評価になります。
また、Iteratorオブジェクトの.toArray()メソッドを使うと、配列に戻すことができます。

配列操作の遅延評価
 const result = [0, 1, 2]
+    .values()
     .map(val => val + 1)
     .map(val => val ** 2)
+    .toArray();

例:無限イテレータ

通常の配列操作の場合、無限の長さを持つ配列は扱えません(当然ですね)。
一方、Iteratorオブジェクトを使って遅延評価を行う場合は、無限に値を取り出せるイテレータを作って操作することができます。

今回は無限イテレータを作成しmapで変換したのち、takeメソッドを使って先頭3個を取り出すコードを書いてみましょう。

無限イテレータの操作
// 無限イテレータを作成する関数
function* infinityIterator() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

infinityIterator() // 無限イテレータを生成
    .map(val => val + 1)
    .map(val => val ** 2)
    .take(3)    // 先頭3個を取り出し
    .toArray(); // [1, 4, 9]

これがもし配列なら、1回目のmapの際に無限ループに陥り、プログラムが止まらなくなってしまうはずです。
しかし、イテレータは遅延評価されるという性質があるため、最後に.take(3)で先頭3個を取り出せば、後ろの4番目以降の値については計算されず、無限ループを回避できます。

このように、Iteratorオブジェクトを使って遅延評価することで、無駄な計算処理を省くことができます。また、中間配列の生成を避けることができるため、処理の高速化も期待できます。

まとめ

  • JavaScriptで配列の遅延評価ができる「Iterator Helpers」がもうすぐ導入予定
  • 「Iterator Helpers」を使って配列操作を遅延評価するには、.values()Iteratorオブジェクトに変換する
  • 遅延評価することで、不要な計算を回避したり、中間配列の生成を避けることができたりといったメリットがある

Iteratorオブジェクトには、今回紹介したmaptake以外にも、便利なメソッドが揃っています。導入が待ち遠しいですね!

関連記事

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1