Javascript 合并/展平一组数组
我有一个JavaScript数组,如:Javascript 合并/展平一组数组,javascript,arrays,flatten,Javascript,Arrays,Flatten,我有一个JavaScript数组,如: [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]] 如何将单独的内部阵列合并为一个类似于: ["$6", "$12", "$25", ...] 您可以使用concat合并数组: var数组=[ ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"] ]; var merged=[].concat.apply([]
[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
如何将单独的内部阵列合并为一个类似于:
["$6", "$12", "$25", ...]
您可以使用
concat
合并数组:
var数组=[
["$6"],
["$12"],
["$25"],
["$25"],
["$18"],
["$22"],
["$10"]
];
var merged=[].concat.apply([],数组);
console.log(合并)代码>要展平单个元素数组的数组,您不需要导入库,简单循环是最简单的解决方案:
for (var i = 0; i < a.length; i++) {
a[i] = a[i][0];
}
for(变量i=0;i
反对者:请阅读这个问题,不要反对,因为它不适合你完全不同的问题。此解决方案对于所问问题来说是最快和最简单的。这并不难,只需迭代数组并合并它们:
var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];
for (var i = 0; i < input.length; ++i) {
result = result.concat(input[i]);
}
var结果=[],输入=[“$6”],[“$12”],[“$25”],[“$25”],[“$18”];
对于(变量i=0;i
您可以使用:
如果只有包含1个字符串元素的数组:
[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');
我会做好的。这是一个简短的函数,它使用一些较新的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]
有一个令人困惑的隐藏方法,它构造一个新数组而不改变原始数组:
var oldArray=[[1]、[2,3]、[4];
var newArray=Array.prototype.concat.apply([],oldArray);
console.log(newArray);//[1,2,3,4]
使用reduce(回调[,initialValue])
方法JavaScript 1.8
list.reduce((p,n) => p.concat(n),[]);
将完成这项工作。对于更一般的情况,当您的数组中可能有一些非数组元素时,这是一个解决方案
function flattenArrayOfArrays(a, r){
if(!r){ r = []}
for(var i=0; i<a.length; i++){
if(a[i].constructor == Array){
r.concat(flattenArrayOfArrays(a[i], r));
}else{
r.push(a[i]);
}
}
return r;
}
函数展平阵列远射线(a,r){
如果(!r){r=[]}
对于(var i=0;i来说,最好通过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), []);
这看起来像是递归的工作
- 处理多级嵌套
- 处理空数组和非数组参数
- 没有突变
- 不依赖现代浏览器功能
代码:
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 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]
(基于@danhbear的评论,我只是将此作为一个单独的答案来写。)我已经使用递归和闭包完成了
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;
}
函数展平(arr){
var-temp=[];
函数递归展平(arr){
对于(变量i=0;i
更新:原来此解决方案不适用于大型阵列。如果您正在寻找更好、更快的解决方案,请查看。
只需扩展arr
,并将其作为参数传递给concat()
,它将所有数组合并为一个数组。它相当于[].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
)
)
}
请参阅上的演示
此答案中使用的ECMAScript 6元素的参考:
旁注:并非所有浏览器都支持像find()
和arrow函数这样的方法,但这并不意味着你现在不能使用这些功能。只需使用-它就可以将ES6代码转换为ES5。我前几天在闲逛并编写了。其中包含
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);
基本上,我正在创建一个在原始输入数组上循环的生成器,如果它找到一个数组,它将使用操作符与递归相结合来不断展平内部数组。如果项不是数组,它只是单个项。然后使用(也称为splat操作符)将生成器展平到一个新的数组实例中
我还没有测试过它的性能,但我认为这是一个使用生成器和yield*操作符的简单示例
不过,我还是在胡闹,所以我相信还有更多更高性能的方法可以做到这一点。另一个功能型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 flatte=arr=>arr.reduce(
(a,b)=>a.concat(Array.isArray(b)?展平(b):b),[]
);
log(展平([1,2,3],[4,5],[6,7,8,9,10,11],[12,13])
这里的大多数答案对大型(例如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;
};
在我的机器上,这段代码大约需要14毫秒才能执行
嵌套数组
它与嵌套数组一起工作。此代码生成[1,1,1,1,1,1]
具有不同嵌套级别的数组
像这样展平阵列没有任何问题。请注意:当函数.prototype.apply
([].concat.apply([],阵列)
)或扩展操作符([].concat(…阵列)
)用于展平数组,两者都会导致大型数组的堆栈溢出,因为函数的每个参数都存储在堆栈上
下面是一个功能风格的堆栈安全实现,它将最重要的需求相互权衡:
- 可重用性
- 可读性
- 简洁
- 演出
//小的、可重用的辅助函数:
const foldl=f=>acc=>xs=>xs.reduce(uncurry(f),acc);//又称reduce
未成熟常数=f=>(a,b)=>f(a)(b);
const concat=xs=>y=>xs.concat(y);
//展平阵列的实际功能—一条不言自明的直线:
常数展平=xs=>foldl(concat)([])(xs);
//任意数组大小(直到堆爆炸:D)
常数xs=[[1,2,3],[4,5,6],[7,8,9];
console.log(展平(xs)
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]));
flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));
flatten([1, [1], [[1]]]);
let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))
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]);
});
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]);
});
const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
// Flatten 2 levels deep
const arr3 = [2, 2, 5, [5, [5, [6]], 7]];
arr3.flat(2);
// [2, 2, 5, 5, 5, [6], 7];
// Flatten all levels
const arr4 = [2, 2, 5, [5, [5, [6]], 7]];
arr4.flat(Infinity);
// [2, 2, 5, 5, 5, 6, 7];
const common = arr.reduce((a, b) => [...a, ...b], [])