JavaScriptの便利ツール `Array.flat()` でネストをバッサリ! 詳細ガイドと代替方法も


Array.flat() の動作

Array.flat() メソッドは、再帰的にネストされた配列をすべてフラット化します。つまり、すべてのサブ配列を、その要素に置き換えます。この処理は、引数として渡された depth の値まで繰り返されます。

  • 負の depth 値は、無限大の深さまでフラット化することを意味します。
  • depth 引数が 1 の場合、2階層までのすべてのサブ配列がフラット化されます。
  • depth 引数が省略された場合、または 0 に設定された場合、1階層のみがフラット化されます。

以下の例をご覧ください。

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];

console.log(originalArray.flat());
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

上記の例では、depth 引数が省略されているため、originalArray の 1 階層のみがフラット化され、結果として [1, 2, 3, 4, 5, 6, 7, 8, 9] という 1次元の配列が得られます。

Array.flat() の利点

Array.flat() メソッドを使用する利点は次のとおりです。

  • パフォーマンスの向上: 特定の操作において、Array.flat() は従来のフラット化方法よりも効率的に動作する場合があります。
  • 読みやすいコード: コードがより平坦になり、理解しやすくなります。
  • 簡潔なコード: ネストされた配列を処理するために、複雑な再帰呼び出しや for ループを使用する必要がなくなります。
  • すべての状況で Array.flat() が最適とは限りません。単純な配列の場合、従来のフラット化方法の方が高速で効率的な場合もあります。
  • depth 引数の値によっては、処理速度が遅くなる可能性があります。
  • Array.flat() は比較的新しいメソッドであり、古いブラウザではサポートされていない場合があります。


例 1:ネストされた配列を 1 階層フラット化

この例では、depth 引数を省略して、ネストされた配列を 1 階層フラット化します。

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];

console.log(originalArray.flat());
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

この例では、depth 引数を 1 に設定して、ネストされた配列を 2 階層フラット化します。

const originalArray = [1, [2, [3, 4]], 5, [[6], 7, 8]];

console.log(originalArray.flat(2));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8]

例 3:すべてのネストをフラット化

この例では、depth 引数に -1 を設定して、すべてのネストをフラット化します。

const originalArray = [1, [[2, [3, 4]], 5], [[[6]]], 7, 8];

console.log(originalArray.flat(Infinity));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8]

Array.flat() メソッドは、Array.flatMap() メソッドと似ています。ただし、Array.flatMap() は、各要素を処理するために渡されるコールバック関数を受け取ることができます。このコールバック関数は、各要素を新しい値またはサブ配列に変換することができます。

const originalArray = [1, [2, 3, 4], 5, [6, 7, 8]];

console.log(originalArray.flatMap(x => x.length === 1 ? x[0] : x));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8]


手動による再帰処理

最も基本的な方法は、再帰関数を使用してネストされた配列をを手動でフラット化することです。これは、比較的単純な方法ですが、コードが冗長になり、エラーが発生しやすいという欠点があります。

function flatten(array) {
  const result = [];
  for (const element of array) {
    if (Array.isArray(element)) {
      result.push(...flatten(element));
    } else {
      result.push(element);
    }
  }
  return result;
}

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];
console.log(flatten(originalArray));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

reduce() メソッドの使用

reduce() メソッドを使用して、ネストされた配列をフラット化することもできます。この方法は、再帰処理よりも簡潔で、読みやすいコードを作成できます。

function flatten(array) {
  return array.reduce((acc, current) => {
    if (Array.isArray(current)) {
      return acc.concat(flatten(current));
    } else {
      return acc.concat(current);
    }
  }, []);
}

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];
console.log(flatten(originalArray));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

forEach() メソッドと push() メソッドの使用

forEach() メソッドと push() メソッドを使用して、ネストされた配列をフラット化することもできます。この方法は、比較的単純ですが、reduce() メソッドよりも冗長になる可能性があります。

function flatten(array) {
  const result = [];
  array.forEach(element => {
    if (Array.isArray(element)) {
      element.forEach(subelement => result.push(subelement));
    } else {
      result.push(element);
    }
  });
  return result;
}

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];
console.log(flatten(originalArray));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

ライブラリの使用

lodashunderscore などのライブラリには、flatten() メソッドを提供しているものがあります。これらのライブラリを使用すると、簡潔で読みやすいコードでネストされた配列をフラット化することができます。

const _ = require('lodash');

const originalArray = [1, [2, 3, 4], 5, [6, [7, 8, 9]]];
console.log(_.flatten(originalArray));
// 結果: [1, 2, 3, 4, 5, 6, 7, 8, 9]

どの方法を選択するべきか

使用する方法は、状況によって異なります。

  • ライブラリを使用することに抵抗がない場合は、lodashunderscore などのライブラリを使用することができます。
  • 汎用的な方法が必要であれば、reduce() メソッドを使用することができます。
  • コードの制御性を高めたい場合は、手動による再帰処理を使用することができます。
  • コードが簡潔で読みやすいことが重要であれば、Array.flat() メソッドを使用するのがおすすめです。