我有一个JavaScript数组,如:

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

如何将单独的内部数组合并为一个,例如:

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

当前回答

这是一个基于artif3x答案的Typescript版本,为Scala粉丝提供了flatMap的额外实现。

function flatten<T>(items: T[][]): T[] {
  return items.reduce((prev, next) => prev.concat(next), []);
}

function flatMap<T, U>(items: T[], f: (t: T) => U[]): U[] {
  return items.reduce((prev, next) => prev.concat(f(next)), new Array<U>());
}

其他回答

看起来这看起来像是一份招聘工作!

处理多层嵌套处理空数组和非数组参数没有突变不依赖现代浏览器功能

代码:

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] 

我知道这有点粗糙,但我所知道的扁平化字符串数组(任何深度!)(没有逗号!)的唯一简洁方法是将数组转换为字符串,然后用逗号分割字符串:

var myArray =[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];
var myFlatArray = myArray.toString().split(',');

myFlatArray;
// ["$6", "$12", "$25", "$25", "$18", "$22", "$10", "$0", "$15", "$3", "$75", "$5", "$100", "$7", "$3", "$75", "$5"]

这应该适用于任何深度的仅包含字符串和数字(整数和浮点)的嵌套数组,但需要注意的是,数字将在过程中转换为字符串。这可以通过一点映射来解决:

var myArray =[[[1,2],[3,4]],[[5,6],[7,8]],[[9,0]]];
var myFlatArray = myArray.toString().split(',').map(function(e) { return parseInt(e); });
myFlatArray;
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 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安慰

可以将Array.flat()与Infinity一起用于任何深度的嵌套数组。

var arr=[[1,2,3,4],[1,2,[1,2,3]],[1,2,4,5,[1,3,4,[12,3,4,[12,3,4]]],[[1,2,3-4],[1,3,[1,2],[1,2,3,5],[1,3,4,[1,2,3,4]]];let flatten=arr.flat(无限)console.log(展平)

在此处检查浏览器兼容性

这里的大多数答案都不适用于大型(例如200000个元素)阵列,即使这样,它们也很慢。

以下是最快的解决方案,它也适用于具有多层嵌套的阵列:

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,2,1,3,1,1]。

具有不同嵌套级别的数组

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

它对像这样的扁平化阵列没有任何问题。