有没有一种简单的方法可以将嵌套数组变成平面的?

14

将这个:

[ ['dog','cat', ['chicken', 'bear'] ],['mouse','horse'] ]

转换成:

['dog','cat','chicken','bear','mouse','horse']


2
你可以简单地用空字符串替换所有的 [],然后添加一个开头和结尾的括号。 - pimvdb
1
那个东西到底应该叫什么,是对象还是数组? - rsk82
1
一个数组。请查看http://tech.karbassi.com/2009/12/17/pure-javascript-flatten-array/。 - Swift
@Mike,那个页面上的代码非常可怕,依赖于解析Array.prototype.toString()的输出。我的下面的代码确实可以工作。 - Alnitak
使用扁平化方法 arr.flat(Infinity); - Mahesh Jamdade
12个回答

28
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
  return a.concat(b);
});
// flattened is [0, 1, 2, 3, 4, 5]

值得注意的是,在IE 8及更低版本中不支持reduce方法。

developer.mozilla.org参考文献


2
这并不是 OP 想要的。它会产生 ["dog","cat",["chicken","bear"],"mouse","horse"],内部数组仍然作为一个数组而不是将其元素展平。 - Craig M
没错,我只是想让他明白这个概念,看起来他从中理解了。 - ChewOnThis_Trident

24

在现代浏览器中,您可以只用几行代码而不需要任何外部库来实现此功能:

Array.prototype.flatten = function() {
  return this.reduce(function(prev, cur) {
    var more = [].concat(cur).some(Array.isArray);
    return prev.concat(more ? cur.flatten() : cur);
  },[]);
};

console.log([['dog','cat',['chicken', 'bear']],['mouse','horse']].flatten());
//^ ["dog", "cat", "chicken", "bear", "mouse", "horse"]

10

下载underscore.js并使用flatten函数。

_.flatten([ ['dog','cat', ['chicken', 'bear'] ],['mouse','horse'] ]);

这应该是被接受的答案。没有必要重新发明轮子 :) - Marco Sulla
1
有些人不想为了一个功能而加载一个新的脚本! - Rathma

7
这个一行代码怎么样?

console.log([['dog', 'cat', ['chicken', 'bear']], [['mouse', 'horse'], 'lion']].join().split(','));

基本上,join方法可以从嵌套的数组中生成逗号分隔的字符串。使用split方法可以获取一维数组。很不错吧?额外奖励它也可以在所有主流浏览器上运行 :)


6

对 ChewOnThis_Trident 的解决方案进行小修补,现在它完美运作:

Array.prototype.flatten = function() {
    return this.reduce(function(a, b) {
        return a.concat(b);
    }, []);
};

4
假设有一个已经从JSON中解包的数组,请尝试以下操作:
Array.prototype.flatten = function() {
    var r = [];
    for (var i = 0; i < this.length; ++i) {
        var v = this[i];
        if (v instanceof Array) {
            Array.prototype.push.apply(this, v.flatten());
        } else {
            r.push(v);
        }
    }
    return r;
};

看起来它在你的输入上运行正常 - 请参阅http://jsfiddle.net/alnitak/Ws7L5/


这并不一定是正确的,可以看看http://jsfiddle.net/theycallmeswift/qfpGK/1/ - Swift
是的,警告已经被压缩了。console.log() 显示正确的结果。 - Alnitak
下投票给那些因为意外的alert()行为没有正确显示结果,但实际上代码是有效的,这是很严厉的。 - Alnitak

3

现在在2019年,您可以轻松地使用 Array.flat 以任意深度。

let arr  = [ ['dog','cat', ['chicken', 'bear'] ],['mouse','horse'] ]

let op = arr.flat(Infinity)

console.log(op)

如果您想获取唯一的值,可以将Set和flat结合使用。

let arr  = [ ['dog','cat', ['chicken', 'bear', 'cat'] ],['mouse','horse', 'dog'], [[[['deeper','chicken']]]] ]

let unique  = [...new Set(arr.flat(Infinity))]

console.log(unique)
Browser comparability Except IE all other seems to support for IE you can use polyfill.


有一个随机问题,什么是查看Node与Chrome版本对应关系的最佳资源?在尝试在Node 10.15.3中使用array.flat()时发现这个线程,尽管它似乎是一个有效的Chrome JS函数,但它失败了。 - sirclesam

1

我知道现在有点晚了,但我也遇到了需要将多维数组转换为一维数组的情况,我写了一个函数如下。

function nested(arr) {
    var noNest = arr.toString().split(',').filter(Boolean),
        i = 0;

    for(i;i<noNest.length; i++){
        if(isNaN(noNest[i])){
            return console.log(noNest);
        } else {
            noNest[i] = parseInt(noNest[i]);
        }
    }
    return console.log(noNest);
}

nested([[['a']], [['b']]]);

这也会获取测试数组中嵌套的数组,并确保其作为最终输出的一个数组。

我不需要在上面加过滤器,但是目前这会自动将字符串类型的数字转换为整数,但这很容易进行编辑。我相信有人也会发现这很有用,不会像我一样绕圈子。 - TrojanMorse

1
这个解决方案对我非常有效,我发现它特别易于理解:
function flattenArray(arr) {
  // the new flattened array
  var newArr = [];

  // recursive function
  function flatten(arr, newArr) {
    // go through array
    for (var i = 0; i < arr.length; i++) {
      // if element i of the current array is a non-array value push it
      if (Array.isArray(arr[i]) === false) {
        newArr.push(arr[i]);
      }
      // else the element is an array, so unwrap it
      else {
        flatten(arr[i], newArr);
      }
    }
  }

  flatten(arr, newArr);

  return newArr;
}

1
使用flat方法是将任意深度的对象展平的最简单方法。
var arr = [['dog','cat', ['chicken', 'bear']],[['mouse','horse'],'lion'] ]; 
var flattened = arr.flat(Infinity);
//output--> ["dog", "cat", "chicken", "bear", "mouse", "horse", "lion"]

更多关于Flat()的内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接