No history yet

最新のデータ操作手法

高度なデータグルーピング

日々の業務では、特定の条件に基づいて配列内のデータを分類する必要がよくあります。例えば、ユーザーのリストを役割ごとにまとめたり、商品のリストをカテゴリ別に整理したりするケースです。従来、この処理は reduce メソッドを使って手動で実装するのが一般的でした。

const products = [
  { name: 'Laptop', category: 'Electronics' },
  { name: 'T-shirt', category: 'Apparel' },
  { name: 'Keyboard', category: 'Electronics' },
  { name: 'Jeans', category: 'Apparel' },
];

// 従来のグルーピング方法
const groupedByCategory = products.reduce((acc, product) => {
  const key = product.category;
  if (!acc[key]) {
    acc[key] = [];
  }
  acc[key].push(product);
  return acc;
}, {});

console.log(groupedByCategory);
/*
{
  Electronics: [ { name: 'Laptop', ... }, { name: 'Keyboard', ... } ],
  Apparel: [ { name: 'T-shirt', ... }, { name: 'Jeans', ... } ]
}
*/

このコードは機能しますが、少し冗長です。ES2024で導入された Object.groupBy() を使うと、この一般的なパターンを一行で、より宣言的に記述できます。

// Object.groupBy() を使った新しい方法
const grouped = Object.groupBy(products, product => product.category);

console.log(grouped);

結果は reduce の例と同じですが、コードの意図がはるかに明確になります。Object.groupBy() は、第二引数で渡されたコールバック関数が返す値をキーとして、新しいオブジェクトを生成します。このとき生成されるオブジェクトは、Object.create(null) で作られるため、プロトタイプチェーンを持ちません。これにより、意図しないプロパティ(例: toString)との衝突を避けられます。

同様の機能を持つ Map.groupBy() もあります。こちらは、キーに文字列以外の値(オブジェクトや数値など)を使いたい場合に便利で、結果として標準の Map オブジェクトを返します。

副作用のない配列操作

JavaScriptの sort()reverse() のような従来の配列メソッドには、一つ注意点があります。それは、元の配列を直接変更してしまうことです。これは「」と呼ばれ、特にReactのような宣言的なUIライブラリを使用している場合に、予期せぬバグの原因となることがあります。状態の変更を追跡するのが難しくなるためです。

データを変更するのではなく、変更された新しいデータのコピーを作成するアプローチは「イミュータビリティ(不変性)」と呼ばれます。

この問題を解決するため、元の配列を変更しない「非破壊的」な新しいメソッドが導入されました。

破壊的メソッド (従来)非破壊的メソッド (新規)説明
sort()toSorted()配列をソートした新しい配列を返す
reverse()toReversed()配列を逆順にした新しい配列を返す
splice()toSpliced()配列の一部を削除・置換した新しい配列を返す
arr[i] = valuewith(index, value)指定したインデックスの要素を置き換えた新しい配列を返す

これらの新しいメソッドを使うことで、元のデータを安全に保ちながら、必要な操作を行うことができます。

const originalNumbers = [3, 1, 4, 2];

// toSorted() は新しい配列を返す
const sortedNumbers = originalNumbers.toSorted();
console.log(sortedNumbers); // [1, 2, 3, 4]
console.log(originalNumbers); // [3, 1, 4, 2] (元の配列は変更されない)

// with() で特定要素を置き換える
const updatedNumbers = originalNumbers.with(1, 99);
console.log(updatedNumbers); // [3, 99, 4, 2]
console.log(originalNumbers); // [3, 1, 4, 2] (元の配列は変更されない)

巨大なデータを効率的に扱う

数十万件、数百万件といった巨大なデータセットを扱うとき、mapfilter を使って一連の処理を行うと、各ステップで巨大な中間配列が生成され、メモリを圧迫することがあります。例えば、巨大なログファイルから特定のエラーを探し、最初の10件だけを取得するようなケースを考えてみましょう。

ES2025で導入された は、この問題を解決します。これは、「」というアプローチを取ることで、必要なデータだけを、必要なタイミングで処理します。これにより、メモリ使用量を劇的に削減できます。

// usersは巨大なユーザーリストのイテレータと仮定
function* generateLargeUserList() {
  let id = 0;
  while(id < 1000000) {
    yield { id: id++, isActive: Math.random() > 0.5, name: `User ${id}` };
  }
}

const usersIterator = generateLargeUserList();

// Iterator Helpers を使った処理
const firstFiveActiveUsers = usersIterator
  .filter(user => user.isActive)
  .map(user => user.name)
  .take(5); // 最初の5件が見つかった時点で処理を停止

// toArray()が呼ばれるまで、実際の処理はほとんど実行されない
const result = firstFiveActiveUsers.toArray(); 

console.log(result); 
// 例: [ 'User 2', 'User 5', 'User 6', 'User 8', 'User 11' ]

この例では、filtermap は中間配列を生成しません。代わりに、次の処理ステップを定義した新しいイテレータを返します。最終的に take(5) が5つの要素を見つけた時点で、全体の処理が停止します。100万件すべてのユーザーをメモリに読み込むことなく、効率的に目的の結果を得ることができるのです。

Setの集合演算

Setオブジェクトはユニークな値のコレクションを扱うのに便利ですが、これまで複数のSet間で和集合や積集合といった操作を行うには、手動でループ処理などを書く必要がありました。

最近のJavaScriptでは、これらの一般的な集合演算を行うためのメソッドがSetのプロトタイプに直接追加され、コードが大幅に簡潔になりました。

const setA = new Set([1, 2, 3, 4]);
const setB = new Set([3, 4, 5, 6]);

// 和集合 (A ∪ B)
const unionSet = setA.union(setB);
console.log(unionSet); // Set(6) { 1, 2, 3, 4, 5, 6 }

// 積集合 (A ∩ B)
const intersectionSet = setA.intersection(setB);
console.log(intersectionSet); // Set(2) { 3, 4 }

// 差集合 (A - B)
const differenceSet = setA.difference(setB);
console.log(differenceSet); // Set(2) { 1, 2 }

これらのメソッドは、数学的な集合の概念を直感的にコードに落とし込むことを可能にし、データの比較やフィルタリングをよりエレガントに記述できます。

Quiz Questions 1/5

ES2024で導入された Object.groupBy() メソッドの主な利点は何ですか?

Quiz Questions 2/5

JavaScriptの sort() メソッドは元の配列を直接変更しますが、この振る舞いは「副作用」と呼ばれます。

これらの新しいデータ操作テクニックは、コードをよりクリーンで、効率的で、安全なものにします。特にイミュータブルな操作と遅延評価は、現代的なアプリケーション開発における重要なパラダイムです。状況に応じてこれらの手法を使い分けることで、より質の高いコードを書くことができるようになります。