zan*_*ngw 31 javascript arrays
我们知道,[[0, 1], [2, 3], [4, 5]]使用该方法展平数组reduce()
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
Run Code Online (Sandbox Code Playgroud)
因此,如何扁平化这个数组[[[0], [1]], [[2], [3]], [[4], [5]]]来[0, 1, 2, 3, 4, 5]?
Leo*_*Leo 43
递归的完美用例,可以处理更深层次的结构:
function flatten(ary) {
var ret = [];
for(var i = 0; i < ary.length; i++) {
if(Array.isArray(ary[i])) {
ret = ret.concat(flatten(ary[i]));
} else {
ret.push(ary[i]);
}
}
return ret;
}
flatten([[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]]) // [0, 1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
或者,作为Array方法:
Array.prototype.flatten = function() {
var ret = [];
for(var i = 0; i < this.length; i++) {
if(Array.isArray(this[i])) {
ret = ret.concat(this[i].flatten());
} else {
ret.push(this[i]);
}
}
return ret;
};
[[[[[0]], [1]], [[[2], [3]]], [[4], [5]]]].flatten() // [0, 1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
编辑:嗯,认为它有点功能方式(除了命名的递归应该使用Y-combinator纯功能:D).
function flatten(ary) {
return ary.reduce(function(a, b) {
if (Array.isArray(b)) {
return a.concat(flatten(b))
}
return a.concat(b)
}, [])
}
Run Code Online (Sandbox Code Playgroud)
让我们采用一些ES6语法,使其更短,在一行中.
const flatten = (ary) => ary.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), [])
Run Code Online (Sandbox Code Playgroud)
但请记住,这个不能用作数组方法,因为箭头函数没有自己的this.
Ink*_*ing 41
ES6风格的递归:
function flatten(arr) {
const flat = [].concat(...arr);
return flat.some(Array.isArray) ? flatten(flat) : flat;
}
Run Code Online (Sandbox Code Playgroud)
效率不高,所以除了相对琐碎的情况外,不要使用任何东西,但它至少看起来不错.
2018年6月更新:
现在有一个Array.prototype.flat方法的ES提议.它目前处于第3阶段,这意味着它可能很快就会被浏览器实现(ish),并使其成为当前形式的规范.可能有一些聚四氟乙烯漂浮在周围.
例:
const nested = [[[0], [1]], [[2], [3]], [[4], [5]]];
const flattened = nested.flat(2); // Need to specify depth if > 1
Run Code Online (Sandbox Code Playgroud)
axe*_*uch 32
这是递归的替代方法(请参阅此处的jsfiddle),并且应该接受任何级别的深度,以避免堆栈溢出.
var array = [[0, 1], [2, 3], [4, 5, [6, 7, [8, [9, 10]]]]];
console.log(flatten(array), array); // does not mutate array
console.log(flatten(array, true), array); // array is now empty
// This is done in a linear time O(n) without recursion
// memory complexity is O(1) or O(n) if mutable param is set to false
function flatten(array, mutable) {
var toString = Object.prototype.toString;
var arrayTypeStr = '[object Array]';
var result = [];
var nodes = (mutable && array) || array.slice();
var node;
if (!array.length) {
return result;
}
node = nodes.pop();
do {
if (toString.call(node) === arrayTypeStr) {
nodes.push.apply(nodes, node);
} else {
result.push(node);
}
} while (nodes.length && (node = nodes.pop()) !== undefined);
result.reverse(); // we reverse result to restore the original order
return result;
}Run Code Online (Sandbox Code Playgroud)
mat*_*nso 13
ES6单线:
function flatten(a) {
return Array.isArray(a) ? [].concat(...a.map(flatten)) : a;
}
Run Code Online (Sandbox Code Playgroud)
此外,非深层数组的非递归版本(效率不高但相当优雅)
function flatten(a) {
var queue = a.slice();
var result = [];
while(queue.length) {
let curr = queue.pop();
if(Array.isArray(curr)) {
queue.push(...curr);
}
else result.push(curr);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
Tim*_* Gu 10
基于@Leo的解决方案,但通过重用相同的阵列并防止更快 .concat
function flatten(ary, ret) {
ret = ret === undefined ? [] : ret;
for (var i = 0; i < ary.length; i++) {
if (Array.isArray(ary[i])) {
flatten(ary[i], ret);
} else {
ret.push(ary[i]);
}
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
例:
function flatten(ary, ret) {
ret = ret === undefined ? [] : ret;
for (var i = 0; i < ary.length; i++) {
if (Array.isArray(ary[i])) {
flatten(ary[i], ret);
} else {
ret.push(ary[i]);
}
}
return ret;
}
console.log(flatten([[[0], [1]], [[2], [3]], [[4], [5]]]));Run Code Online (Sandbox Code Playgroud)
或者Array.prototype.reduce,因为你提到它:
function flatten(ary, ret) {
return ary.reduce(function(ret, entry) {
if (Array.isArray(entry)) {
flatten(entry, ret);
} else {
ret.push(entry);
}
return ret;
}, ret || []);
}
Run Code Online (Sandbox Code Playgroud)
例:
function flatten(ary, ret) {
return ary.reduce(function(ret, entry) {
if (Array.isArray(entry)) {
flatten(entry, ret);
} else {
ret.push(entry);
}
return ret;
}, ret || []);
}
console.log(flatten([[[0], [1]], [[2], [3]], [[4], [5]]]));Run Code Online (Sandbox Code Playgroud)
仅展平2个级别:
var arr = [1, [2, 3], [4, 5, 6]];
[].concat.apply([], arr) // -> [1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
小智 5
这已经得到了回答,但我只是在学习 JS 并想知道:
var array = [[[0], [1]], [[2], [3]], [[4], [5]]];
var flattend = array.join(",").split(",");
console.log(flattend);
Run Code Online (Sandbox Code Playgroud)
唯一的副作用是连接将所有项目转换为字符串,但这可以很容易地修复
我喜欢我的解决方案:)
var flattenClosure = function(a) {
var store = [];
return function() {
var internMapper = function(b) {
if (Array.isArray(b)) {
return b.map(internMapper);
}
store.push(b);
return b;
}
a.map(internMapper);
return store;
}
};
console.log(flattenClosure([[[[[[[[1]]]], [2], [4], [6, 8, 9], 2]]], 10, 11, [15, 17, 20], [], 33])());
Run Code Online (Sandbox Code Playgroud)