1400

次のような JavaScript 配列があります。

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

個別の内部配列を次のようなものにマージするにはどうすればよいですか。

["$6", "$12", "$25", ...]
4

83 に答える 83

2311

concat配列をマージするために使用できます。

var arrays = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];
var merged = [].concat.apply([], arrays);

console.log(merged);

applyのメソッドを使用するconcatと、2 番目のパラメーターを配列として受け取るだけなので、最後の行は次のようになります。

var merged2 = [].concat(["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]);

Array.prototype.flat()配列をフラット化するために使用できるメソッド (ES2019 で導入) もありますが、バージョン 11 以降の Node.js でのみ使用でき、 Internet Explorer ではまったく使用できません

const arrays = [
      ["$6"],
      ["$12"],
      ["$25"],
      ["$25"],
      ["$18"],
      ["$22"],
      ["$10"]
    ];
const merge3 = arrays.flat(1); //The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
console.log(merge3);
    

于 2012-06-02T18:56:33.400 に答える
580

以下は、新しい JavaScript 配列メソッドのいくつかを使用して n 次元配列を平坦化する短い関数です。

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []);
}

使用法:

flatten([[1, 2, 3], [4, 5]]); // [1, 2, 3, 4, 5]
flatten([[[1, [1.1]], 2, 3], [4, 5]]); // [1, 1.1, 2, 3, 4, 5]
于 2013-02-22T17:41:10.227 に答える
340

元の配列を変更せずに新しい配列を構築する紛らわしい隠しメソッドがあります。

var oldArray = [[1],[2,3],[4]];
var newArray = Array.prototype.concat.apply([], oldArray);
console.log(newArray); // [ 1, 2, 3, 4 ]

于 2013-03-13T22:12:31.610 に答える
237

これは、javascript の reduce 関数で行うのが最適です。

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];

arrays = arrays.reduce(function(a, b){
     return a.concat(b);
}, []);

または、ES2015 の場合:

arrays = arrays.reduce((a, b) => a.concat(b), []);

js-フィドル

Mozilla ドキュメント

于 2013-08-19T05:58:33.050 に答える
84

ここでの回答のほとんどは、巨大な (たとえば 200 000 要素) 配列では機能しません。polkovnikov.ph の回答は最高のパフォーマンスを発揮しますが、深い平坦化には機能しません。

これは、複数レベルのネストを持つ配列でも機能する最速のソリューションです

const flatten = function(arr, result = []) {
  for (let i = 0, length = arr.length; i < length; i++) {
    const value = arr[i];
    if (Array.isArray(value)) {
      flatten(value, result);
    } else {
      result.push(value);
    }
  }
  return result;
};

巨大な配列

flatten(Array(200000).fill([1]));

巨大な配列を問題なく処理します。私のマシンでは、このコードの実行に約 14 ミリ秒かかります。

ネストされた配列

flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));

ネストされた配列で動作します。このコードは を生成し[1, 1, 1, 1, 1, 1, 1, 1]ます。

入れ子のレベルが異なる配列

flatten([1, [1], [[1]]]);

このような配列のフラット化には何の問題もありません。

于 2016-08-17T14:54:05.610 に答える
64

更新: このソリューションは大きな配列では機能しないことが判明しました。より優れた、より高速なソリューションをお探しの場合は、この回答をご覧ください。


function flatten(arr) {
  return [].concat(...arr)
}

は単純に展開arrされ、引数として に渡されます。これによりconcat()、すべての配列が 1 つにマージされます。に相当し[].concat.apply([], arr)ます。

深い平坦化のためにこれを試すこともできます:

function deepFlatten(arr) {
  return flatten(           // return shalowly flattened array
    arr.map(x=>             // with each x in array
      Array.isArray(x)      // is x an array?
        ? deepFlatten(x)    // if yes, return deeply flattened x
        : x                 // if no, return just x
    )
  )
}

JSBinのデモを参照してください。

この回答で使用されている ECMAScript 6 要素の参照:


補足:find()やアロー関数などのメソッドは、すべてのブラウザーでサポートされているわけではありませんが、これらの機能を今すぐ使用できないわけではありません。Babelを使用するだけで、ES6 コードを ES5 に変換できます。

于 2016-01-24T19:31:19.990 に答える
54

アンダースコアを使用できます:

var x = [[1], [2], [3, 4]];

_.flatten(x); // => [1, 2, 3, 4]
于 2012-06-02T18:58:38.203 に答える
45

一般的な手順は、特定の動作を利用する必要があるたびに複雑さを書き直す必要がないことを意味します。

concatMap(またはflatMap) はまさにこの状況で必要なものです。

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.map(f).reduce(concat, [])

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)

// your sample data
const data =
  [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

console.log (flatten (data))

先見の明

そして、はい、あなたはそれを正しく推測しました.1つのレベルのみを平坦化します.これはまさにそれがどのように機能するかです.

このようなデータセットを想像してください

// Player :: (String, Number) -> Player
const Player = (name,number) =>
  [ name, number ]

// team :: ( . Player) -> Team
const Team = (...players) =>
  players

// Game :: (Team, Team) -> Game
const Game = (teamA, teamB) =>
  [ teamA, teamB ]

// sample data
const teamA =
  Team (Player ('bob', 5), Player ('alice', 6))

const teamB =
  Team (Player ('ricky', 4), Player ('julian', 2))

const game =
  Game (teamA, teamB)

console.log (game)
// [ [ [ 'bob', 5 ], [ 'alice', 6 ] ],
//   [ [ 'ricky', 4 ], [ 'julian', 2 ] ] ]

さて、参加するすべてのプレーヤーを示す名簿を印刷したいとしましょうgame

const gamePlayers = game =>
  flatten (game)

gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]

私たちのflatten手順が入れ子になった配列もフラット化した場合、このガベージ結果になってしまいます…

const gamePlayers = game =>
  badGenericFlatten(game)

gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]

ローリン・ディープ、ベイビー

入れ子になった配列を平坦化したくない場合があると言っているわけではありません – ただ、それはデフォルトの動作であってはなりません。

安心してdeepFlatten手続きができる…

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.map(f).reduce(concat, [])

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)

// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)

// your sample data
const data =
  [0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]

console.log (flatten (data))
// [ 0, 1, [ 2, [ 3, [ 4, 5 ], 6 ] ], 7, [ 8 ], 9 ]

console.log (deepFlatten (data))
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

そこには。これで、ジョブごとにツールが用意されました。1 つは 1 レベルのネストを押しつぶすためのものでflatten、もう 1 つはすべてのネストを消去するためのものdeepFlattenです。

多分あなたはそれを呼び出すことができますobliteratenuke、名前が気に入らない場合deepFlatten.


2 回繰り返さないでください。

もちろん、上記の実装は巧妙で簡潔ですが、a の.map後に呼び出しが続く.reduceということは、実際には必要以上の反復を行っていることを意味します。

私が呼んでいる信頼できるコンビネータを使用するとmapReduce、反復を最小限に抑えることができます。m :: a -> bマッピング関数と縮小関数を取り、r :: (b,a) ->b新しい縮小関数を返します。このコンビネータはトランスデューサの心臓部です。興味があれば、それらについて他の回答を書きました

// mapReduce = (a -> b, (b,a) -> b, (b,a) -> b)
const mapReduce = (m,r) =>
  (acc,x) => r (acc, m (x))

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.reduce (mapReduce (f, concat), [])

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)
  
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)

// your sample data
const data =
  [ [ [ 1, 2 ],
      [ 3, 4 ] ],
    [ [ 5, 6 ],
      [ 7, 8 ] ] ]

console.log (flatten (data))
// [ [ 1. 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]

console.log (deepFlatten (data))
// [ 1, 2, 3, 4, 5, 6, 7, 8 ]

于 2016-08-18T19:34:18.917 に答える
37

単一要素配列の配列を平坦化するには、ライブラリをインポートする必要はありません。単純なループは、最も単純で最も効率的なソリューションです。

for (var i = 0; i < a.length; i++) {
  a[i] = a[i][0];
}

反対票を投じる方へ:質問を読んでください。反対票を投じないでください。それはあなたの非常に異なる問題に合わないからです。この解決策は、尋ねられた質問に対して最も速くて簡単です。

于 2012-06-02T18:56:40.337 に答える
33

配列に非配列要素が含まれている可能性がある、より一般的なケースの解決策。

function flattenArrayOfArrays(a, r){
    if(!r){ r = []}
    for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            flattenArrayOfArrays(a[i], r);
        }else{
            r.push(a[i]);
        }
    }
    return r;
}
于 2013-06-06T04:41:54.540 に答える
30

reduce(callback[, initialValue])の方法を使用するのはどうですかJavaScript 1.8

list.reduce((p,n) => p.concat(n),[]);

仕事をするでしょう。

于 2013-04-30T11:40:08.243 に答える
30

関数型スタイルの別の ECMAScript 6 ソリューション:

関数を宣言します。

const flatten = arr => arr.reduce(
  (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);

そしてそれを使用します:

flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]

 const flatten = arr => arr.reduce(
         (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
       );


console.log( flatten([1, [2,3], [4,[5],[6,[7,8,9],10],11],[12],13]) )

最新のブラウザーの最新リリースで利用可能なネイティブ関数Array.prototype.flat() (ES6 向けの提案) も検討してください。@(Константин Ван) と @(Mark Amery) がコメントで言及してくれたことに感謝します。

このflat関数には、配列のネストの予想される深さを指定する 1 つのパラメーターがあり1、既定値は等しくなります。

[1, 2, [3, 4]].flat();                  // -> [1, 2, 3, 4]

[1, 2, [3, 4, [5, 6]]].flat();          // -> [1, 2, 3, 4, [5, 6]]

[1, 2, [3, 4, [5, 6]]].flat(2);         // -> [1, 2, 3, 4, 5, 6]

[1, 2, [3, 4, [5, 6]]].flat(Infinity);  // -> [1, 2, 3, 4, 5, 6]

let arr = [1, 2, [3, 4]];

console.log( arr.flat() );

arr =  [1, 2, [3, 4, [5, 6]]];

console.log( arr.flat() );
console.log( arr.flat(1) );
console.log( arr.flat(2) );
console.log( arr.flat(Infinity) );

于 2016-02-01T10:49:11.690 に答える
13

注:Function.prototype.apply ( [].concat.apply([], arrays)) またはスプレッド演算子 ( ) を使用して配列をフラット化する[].concat(...arrays)と、関数のすべての引数がスタックに格納されるため、どちらも大きな配列のスタック オーバーフローを引き起こす可能性があります。

最も重要な要件を相互に比較検討する関数型スタイルのスタック セーフな実装を次に示します。

  • 再利用性
  • 可読性
  • 簡潔
  • パフォーマンス

// small, reusable auxiliary functions:

const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); // aka reduce

const uncurry = f => (a, b) => f(a) (b);

const concat = xs => y => xs.concat(y);


// the actual function to flatten an array - a self-explanatory one-line:

const flatten = xs => foldl(concat) ([]) (xs);

// arbitrary array sizes (until the heap blows up :D)

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

console.log(flatten(xs));


// Deriving a recursive solution for deeply nested arrays is trivially now


// yet more small, reusable auxiliary functions:

const map = f => xs => xs.map(apply(f));

const apply = f => a => f(a);

const isArray = Array.isArray;


// the derived recursive function:

const flattenr = xs => flatten(map(x => isArray(x) ? flattenr(x) : x) (xs));

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

console.log(flattenr(ys));

カリー化された形式の小さなアロー関数、関数合成、高階関数に慣れるとすぐに、このコードは散文のように読めます。プログラミングは、副作用を含まないため、常に期待どおりに機能する小さな構成要素を組み合わせることだけで構成されます。

于 2016-08-17T21:00:09.287 に答える
13

ES6 1 行フラット化

lodash flattenアンダースコア flatten (shallow true)を参照

function flatten(arr) {
  return arr.reduce((acc, e) => acc.concat(e), []);
}

また

function flatten(arr) {
  return [].concat.apply([], arr);
}

でテスト済み

test('already flatted', () => {
  expect(flatten([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats first level', () => {
  expect(flatten([1, [2, [3, [4]], 5]])).toEqual([1, 2, [3, [4]], 5]);
});

ES6 1 行のディープ フラット化

lodash flattenDeepアンダースコア flattenを参照

function flattenDeep(arr) {
  return arr.reduce((acc, e) => Array.isArray(e) ? acc.concat(flattenDeep(e)) : acc.concat(e), []);
}

でテスト済み

test('already flatted', () => {
  expect(flattenDeep([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats', () => {
  expect(flattenDeep([1, [2, [3, [4]], 5]])).toEqual([1, 2, 3, 4, 5]);
});
于 2018-03-22T22:00:19.397 に答える
9

スペース効率の良いジェネレータ関数をお勧めします:

function* flatten(arr) {
  if (!Array.isArray(arr)) yield arr;
  else for (let el of arr) yield* flatten(el);
}

// Example:
console.log(...flatten([1,[2,[3,[4]]]])); // 1 2 3 4

必要に応じて、次のように平坦化された値の配列を作成します。

let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]
于 2017-05-22T02:32:23.407 に答える
9

文字列要素が 1 つの配列しかない場合:

[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');

仕事をします。あなたのコード例と具体的に一致するBt。

于 2012-06-02T19:18:08.310 に答える
7

ES6 方法:

const flatten = arr => arr.reduce((acc, next) => acc.concat(Array.isArray(next) ? flatten(next) : next), [])

const a = [1, [2, [3, [4, [5]]]]]
console.log(flatten(a))

flattenN 回ネストされた配列の ES3 フォールバックを使用した関数の ES5 の方法:

var flatten = (function() {
  if (!!Array.prototype.reduce && !!Array.isArray) {
    return function(array) {
      return array.reduce(function(prev, next) {
        return prev.concat(Array.isArray(next) ? flatten(next) : next);
      }, []);
    };
  } else {
    return function(array) {
      var arr = [];
      var i = 0;
      var len = array.length;
      var target;

      for (; i < len; i++) {
        target = array[i];
        arr = arr.concat(
          (Object.prototype.toString.call(target) === '[object Array]') ? flatten(target) : target
        );
      }

      return arr;
    };
  }
}());

var a = [1, [2, [3, [4, [5]]]]];
console.log(flatten(a));

于 2017-05-10T12:11:23.043 に答える
6

再帰とクロージャーを使用してそれを行いました

function flatten(arr) {

  var temp = [];

  function recursiveFlatten(arr) { 
    for(var i = 0; i < arr.length; i++) {
      if(Array.isArray(arr[i])) {
        recursiveFlatten(arr[i]);
      } else {
        temp.push(arr[i]);
      }
    }
  }
  recursiveFlatten(arr);
  return temp;
}
于 2015-04-29T12:10:50.557 に答える
5

ロダッシュのない最高のソリューション

let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))
于 2016-09-07T10:20:52.023 に答える
5

先日、 ES6 Generatorsをいじっていて、このgist を書きました。を含む...

function flatten(arrayOfArrays=[]){
  function* flatgen() {
    for( let item of arrayOfArrays ) {
      if ( Array.isArray( item )) {
        yield* flatten(item)
      } else {
        yield item
      }
    }
  }

  return [...flatgen()];
}

var flatArray = flatten([[1, [4]],[2],[3]]);
console.log(flatArray);

基本的に、元の入力配列をループするジェネレーターを作成しています。配列が見つかった場合、yield*演算子を再帰と組み合わせて使用​​し、内部配列を継続的に平坦化します。項目が配列でない場合は、単一の項目が生成されます。次に、ES6 スプレッド オペレーター(別名 splat オペレーター) を使用して、ジェネレーターを新しい配列インスタンスにフラット化します。

私はこれのパフォーマンスをテストしていませんが、ジェネレーターと yield* 演算子を使用した単純な例だと思います。

しかし、繰り返しになりますが、私はただふざけていただけなので、これを行うにはもっとパフォーマンスの高い方法があると確信しています。

于 2016-01-28T22:42:39.943 に答える
4

それは難しいことではありません。配列を反復処理してマージするだけです。

var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];

for (var i = 0; i < input.length; ++i) {
    result = result.concat(input[i]);
}
于 2012-06-02T18:56:43.870 に答える
4

これはRECURSIONの仕事のようです!

  • 複数レベルのネストを処理
  • 空の配列と非配列パラメーターを処理します
  • 変異がない
  • 最新のブラウザ機能に依存しない

コード:

var flatten = function(toFlatten) {
  var isArray = Object.prototype.toString.call(toFlatten) === '[object Array]';

  if (isArray && toFlatten.length > 0) {
    var head = toFlatten[0];
    var tail = toFlatten.slice(1);

    return flatten(head).concat(flatten(tail));
  } else {
    return [].concat(toFlatten);
  }
};

使用法:

flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 
于 2014-04-01T02:36:35.200 に答える
3

再帰を使わない短い解決策を 2 つ提案します。計算の複雑さの観点からは最適ではありませんが、平均的なケースでは問題なく機能します。

let a = [1, [2, 3], [[4], 5, 6], 7, 8, [9, [[10]]]];

// Solution #1
while (a.find(x => Array.isArray(x)))
    a = a.reduce((x, y) => x.concat(y), []);

// Solution #2
let i = a.findIndex(x => Array.isArray(x));
while (i > -1)
{
    a.splice(i, 1, ...a[i]);
    i = a.findIndex(x => Array.isArray(x));
}
于 2016-11-30T16:11:53.330 に答える
3

ここでのロジックは、入力配列を文字列に変換し、すべての括弧 ([]) を削除して、出力を配列に解析することです。これにはES6テンプレート機能を使用しています。

var x=[1, 2, [3, 4, [5, 6,[7], 9],12, [12, 14]]];

var y=JSON.parse(`[${JSON.stringify(x).replace(/\[|]/g,'')}]`);

console.log(y)
于 2017-04-21T11:20:21.803 に答える
2

以下は、最新のブラウザー向けの別のディープ フラット化です。

function flatten(xs) {
  xs = Array.prototype.concat.apply([], xs);
  return xs.some(Array.isArray) ? flatten(xs) : xs;
};
于 2014-01-17T02:56:27.867 に答える
2

現在、これを行うための最良かつ簡単な方法は、このように配列を結合および分割することです。

var multipleArrays = [["$6","$Demo"], ["$12",["Multi","Deep"]], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]]

var flattened = multipleArrays.join().split(",")

このソリューションは複数のレベルで機能し、ワンライナーでもあります。

デモ

ECMAScript 6 の編集

ECMAScript 6 は標準化されているため、動作[].concat.apply([], arrays);を 変更することができます。[].concat(...arrays);

var flattened = [].concat(...input);

デモ

編集 最も効率的なソリューション

この問題を解決する最も効率的な方法は、ループを使用することです。ここで「ops/sec」の速度を比較できます

var flattened=[];
for (var i=0; i<input.length; ++i) {
    var current = input[i];
    for (var j=0; j<current.length; ++j)
        flattened.push(current[j]);
} 

デモ

それが役に立てば幸い

于 2016-01-26T11:32:44.033 に答える
1

2 次元配列を 1 行で平坦化するには、次のようにします。

[[1, 2], [3, 4, 5]].reduce(Function.prototype.apply.bind(Array.prototype.concat))
// => [ 1, 2, 3, 4, 5 ]
于 2014-08-31T19:00:38.743 に答える
1

配列が整数または文字列のみで構成されている場合は、次の汚いハックを使用できます。

var arr = [345,2,[34],2,[524,[5456]],[5456]];
var flat = arr.toString().split(',');

動作します。FF、IE、および Chrome では、他のブラウザーはまだテストされていません。

于 2014-02-04T12:00:53.780 に答える
1

このソリューションは、配列の任意の深さレベル (ネストされた配列構造の深さを指定する) で機能します。

function flatten(obj) {
    var out = [];
    function cleanElements(input) {
        for (var i  in input){
            if (input[i]instanceof Array){
                cleanElements(input[i]);
            }
            else {
                out.push(input[i]);
            }
        }
    }
    cleanElements(obj);
    return (out);
}
于 2019-11-18T08:08:37.653 に答える
1

foo という javascript で配列の配列を定義し、javascript の array concat 組み込みメソッドを使用して、その配列の配列を 1 つの配列にフラット化します。

const foo = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]] 
console.log({foo}); 

const bar = [].concat(...foo) 
console.log({bar});

印刷する必要があります:

{ foo: 
   [ [ '$6' ],
     [ '$12' ],
     [ '$25' ],
     [ '$25' ],
     [ '$18' ],
     [ '$22' ],
     [ '$10' ] ] }
{ bar: [ '$6', '$12', '$25', '$25', '$18', '$22', '$10' ] }
于 2019-07-25T10:56:49.403 に答える
1

関数を再帰的に呼び出して、deepFlatten外部ヘルパー メソッドを使用せずに内部配列を拡張できるようにするのが方法です。

const innerArr = ['a', 'b'];
const multiDimArr = [[1, 2], 3, 4, [5, 6, innerArr], 9];

const deepFlatten = (arr) => {
  const flatList = [];
  arr.forEach(item => {
    Array.isArray(item)
     ? flatList.push(...deepFlatten(item)) // recursive call
     : flatList.push(item)
  });
  return flatList;
}
于 2019-10-14T10:15:56.500 に答える
1

Array.flat() メソッドを使用し続けることで、配列がさらにネストされている場合でも、これを実現できます。

[1,2,3,[2]].flat() 

と同等です

[1,2,3,[2]].flat(1)

入れ子が増えるにつれて、数を増やし続けることができます。

例えば:

[1,[2,[3,[4]]]].flat(3) // [1, 2, 3, 4]

ネストのレベルがわからない場合は、Infinity をパラメーターとして渡すだけです。

[1,2,3,[2,[3,[3,[34],43],[34]]]].flat(Infinity) //[1, 2, 3, 2, 3, 3, 34, 43, 34]
于 2018-04-18T08:58:22.673 に答える
1

私が書いた単純な平坦化ユーティリティ

const flatten = (arr, result = []) => {
    if (!Array.isArray(arr)){
        return [...result, arr];
    }
     arr.forEach((a) => {
         result = flatten(a, result)
    })

    return result
}

console.log(flatten([1,[2,3], [4,[5,6,[7,8]]]])) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]
于 2019-07-25T06:55:31.497 に答える
1

次のコードは、深くネストされた配列を平坦化します。

/**
 * [Function to flatten deeply nested array]
 * @param  {[type]} arr          [The array to be flattened]
 * @param  {[type]} flattenedArr [The flattened array]
 * @return {[type]}              [The flattened array]
 */
function flattenDeepArray(arr, flattenedArr) {
  let length = arr.length;

  for(let i = 0; i < length; i++) {
    if(Array.isArray(arr[i])) {
      flattenDeepArray(arr[i], flattenedArr);
    } else {
      flattenedArr.push(arr[i]);
    }
  }

  return flattenedArr;
}

let arr = [1, 2, [3, 4, 5], [6, 7]];

console.log(arr, '=>', flattenDeepArray(arr, [])); // [ 1, 2, [ 3, 4, 5 ], [ 6, 7 ] ] '=>' [ 1, 2, 3, 4, 5, 6, 7 ]

arr = [1, 2, [3, 4], [5, 6, [7, 8, [9, 10]]]];

console.log(arr, '=>', flattenDeepArray(arr, [])); // [ 1, 2, [ 3, 4 ], [ 5, 6, [ 7, 8, [Object] ] ] ] '=>' [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
于 2017-09-12T07:28:44.373 に答える
0

これが私のバージョンです。より多くのシナリオで使用できる複雑なオブジェクトをフラット化できます。

入力

var input = {
   a: 'asdf',
   b: [1,2,3],
   c: [[1,2],[3,4]],
   d: {subA: [1,2]}
}

コード

関数は次のようになります。

function flatten (input, output) {

  if (isArray(input)) {
    for(var index = 0, length = input.length; index < length; index++){
      flatten(input[index], output);
    }
  }
  else if (isObject(input)) {
    for(var item in input){
      if(input.hasOwnProperty(item)){
        flatten(input[item], output);
      }
    }
  }
  else {
    return output.push(input);
  }
};

function isArray(obj) {
  return Array.isArray(obj) || obj.toString() === '[object Array]';
}

function isObject(obj) {
  return obj === Object(obj);
}

使用法

var output = []

flatten(input, output);

出力

["asdf", 1, 2, 3, 1, 2, 3, 4, 1, 2]

于 2014-03-15T04:40:14.750 に答える
0
[1,[2,3],[4,[5,6]]].reduce(function(p, c) {
    return p.concat(c instanceof Array ? 
                    c.reduce(arguments.callee, []) : 
                    [c]); 
}, []);
于 2013-12-06T00:05:58.783 に答える
0

私は当初、.reduceメソッドを使用して関数を再帰的に呼び出して内部配列を平坦化することを考えていましたが、深くネストされた配列の深くネストされた配列を操作している場合、スタック オーバーフローが発生する可能性があります。concat を使用することも最善の方法ではありません。繰り返しのたびに配列の新しい浅いコピーが作成されるためです。代わりにできることは次のとおりです。

const flatten = arr => {
    for(let i = 0; i < arr.length;) {
        const val = arr[i];
        if(Array.isArray(val)) {
            arr.splice(i, 1, ...val);
        } else {
            i ++;
        }
    }
    return arr;
}

concat を使用して新しい配列を作成したり、関数を再帰的に呼び出したりすることはありません。

http://jsbin.com/firiru/4/edit?js,console

于 2016-10-31T21:32:52.117 に答える
0

IE8 をサポートする必要があり、reduce や isArray などのメソッドを使用できない場合は、次の解決策が考えられます。これは、再帰アルゴリズムを理解するのに役立つ詳細なアプローチです。

function flattenArray(a){

    var aFinal = [];

    (function recursiveArray(a){

        var i,
            iCount = a.length;

        if (Object.prototype.toString.call(a) === '[object Array]') {
            for (i = 0; i < iCount; i += 1){
                recursiveArray(a[i]);
            }
        } else {
            aFinal.push(a);
        }

    })(a);

    return aFinal;

}

var aMyArray = [6,3,4,[12,14,15,[23,24,25,[34,35],27,28],56],3,4];

var result = flattenArray(aMyArray);

console.log(result);
于 2015-06-17T14:11:32.137 に答える
0

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];
var merged = [].concat.apply([], arrays);
alert(merged);

于 2016-01-29T05:52:19.657 に答える
0

Array.prototype.reduce()と を使用して、配列の配列を平坦化できます。Array.prototype.concat()

var data = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]].reduce(function(a, b) {
  return a.concat(b);
}, []);
console.log(data);

関連ドキュメント: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

于 2016-08-11T16:58:36.503 に答える
0

一番上の回答にリストされている merge.concat.apply() メソッドを使用するよりもはるかに高速な方法があります。高速とは、数桁以上高速であることを意味します。これは、環境が ES5 Array メソッドにアクセスできることを前提としています。

var array2d = [
  ["foo", "bar"],
  ["baz", "biz"]
];
merged = array2d.reduce(function(prev, next) {
    return prev.concat(next);
});

jsperf のリンクは次のとおりです: http://jsperf.com/2-dimensional-array-merge

于 2014-10-07T14:17:03.137 に答える
0

「join()」「split()」を使用できます。

let arrs = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];

let newArr = arrs.join(",").split(",");

console.log(newArr); // ["$6", "$12", "$25", "$25", "$18", "$22", "$10"]

さらに、「toString()」「split()」も使用できます。

let arrs = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];

let newArr = arrs.toString().split(",");

console.log(newArr); // ["$6", "$12", "$25", "$25", "$18", "$22", "$10"]

ただし、文字列にコンマが含まれている場合、上記の 2 つの方法はどちらも正しく機能しません

「結合()」「分割()」 :

let arrs = [
  ["$,6"],
  ["$,12"],
  ["$2,5"],
  ["$2,5"],
  [",$18"],
  ["$22,"],
  ["$,1,0"]
];

let newArr = arrs.join(",").split(",");

console.log(newArr); 
// ["$", "6", "$", "12", "$2", "5", "$2", "5", "", "$18", "$22", "", "$", "1", "0"]

"toString()""split()" :

let arrs = [
  ["$,6"],
  ["$,12"],
  ["$2,5"],
  ["$2,5"],
  [",$18"],
  ["$22,"],
  ["$,1,0"]
];

let newArr = arrs.toString().split(",");

console.log(newArr); 
// ["$", "6", "$", "12", "$2", "5", "$2", "5", "", "$18", "$22", "", "$", "1", "0"]

于 2021-12-08T13:42:25.957 に答える
0

特別なjs関数を使用せずに簡単な解決策があります。(削減など)

const input = [[0, 1], [2, 3], [4, 5]]
let flattened=[];

for (let i=0; i<input.length; ++i) {
    let current = input[i];
    for (let j=0; j<current.length; ++j)
        flattened.push(current[j]);
}
于 2018-11-17T19:59:37.560 に答える
-1
Array.prototype.flatten = Array.prototype.flatten || function() {
    return [].reduce.call(this, function(flat, toFlatten) {
        return flat.concat(Array.isArray(toFlatten) ? toFlatten.flatten() : toFlatten);
    },[])
};
于 2016-02-12T19:30:24.873 に答える
-2

ディープフラット化とオブジェクト指向はどうですか?

[23, [34, 454], 12, 34].flatten();
// -->   [23,34, 454, 12, 34]

[23, [34, 454,[66,55]], 12, 34].flatten();

// -->  [23, 34, 454, [66,55], 12, 34]

DEEP フラット化 :

[23, [34, 454,[66,55]], 12, 34].flatten(true);

// --> [23, 34, 454, 66, 55, 12, 34]

デモ

CDN


すべての配列要素が Integer、Float、... または String の場合、次のトリックを実行します。

var myarr=[1,[7,[9.2]],[3],90];
eval('myarr=['+myarr.toString()+']');
print(myarr);
// [1, 7, 9.2, 3, 90]

デモ

于 2014-06-04T18:56:00.533 に答える
-3

これを行う最善の方法は次のようなものだと思います。

var flatten = function () {
  return [].slice.call(arguments).toString().split(',');
};
于 2015-09-24T19:39:44.630 に答える
-4

そこからコードを使用します。

私は次のように書きます。

myArray.enumerable().selectMany(function(x) { return x; }).array()
于 2014-09-24T04:15:50.843 に答える