在JavaScript中连接N个对象数组的最有效的方法是什么?
数组是可变的,结果可以存储在一个输入数组中。
在JavaScript中连接N个对象数组的最有效的方法是什么?
数组是可变的,结果可以存储在一个输入数组中。
concat()方法用于连接两个或多个数组。它不会更改现有数组,只返回已连接数组的副本。
array1 = array1.concat(array2, array3, array4, ..., arrayN);
轻松使用concat函数:
var a = [1,2,3];
var b = [2,3,4];
a = a.concat(b);
>> [1,2,3,2,3,4]
您可以使用jsperf.com站点来比较性能。这是concat的链接。
增加了以下之间的比较:
var c = a.concat(b);
and:
var c = [];
for (i = 0; i < a.length; i++) {
c.push(a[i]);
}
for (j = 0; j < b.length; j++) {
c.push(b[j]);
}
第二款在镀铬的情况下几乎要慢10倍。
如果要连接两个以上的数组,为了方便和可能的性能,concat()是最好的方法。
var a = [1, 2], b = ["x", "y"], c = [true, false];
var d = a.concat(b, c);
console.log(d); // [1, 2, "x", "y", true, false];
对于仅连接两个数组,可以使用push接受多个由要添加到数组的元素组成的参数来将元素从一个数组添加到另一个数组的末尾,而无需生成新数组。对于slice(),它也可以用来代替concat(),但这样做似乎没有性能优势。
var a = [1, 2], b = ["x", "y"];
a.push.apply(a, b);
console.log(a); // [1, 2, "x", "y"];
在ECMAScript 2015及以后的版本中,可以进一步简化为
a.push(...b)
然而,对于大型数组(100,000成员的数量级或更多),将元素数组传递给push(使用apply()或ECMAScript 2015展开操作符)的技术可能会失败。对于这样的数组,使用循环是更好的方法。详情见https://stackoverflow.com/a/17368101/96100。
[].concat.apply([], [array1, array2, ...])
效率证明:http://jsperf.com/multi-array-concat/7
Tim Supinie mentions in the comments that this may cause the interpreter to exceed the call stack size. This is perhaps dependent on the js engine, but I've also gotten "Maximum call stack size exceeded" on Chrome at least. Test case: [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (I've also gotten the same error using the currently accepted answer, so one is anticipating such use cases or building a library for others, special testing may be necessary no matter which solution you choose.)
使用Array.prototype.concat.apply来处理多个数组的连接:
var resultArray = Array.prototype.concat.apply([], arrayOfArraysToConcat);
例子:
var a1 = [1, 2, 3],
a2 = [4, 5],
a3 = [6, 7, 8, 9];
Array.prototype.concat.apply([], [a1, a2, a3]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
如果你正在通过map/filter/sort等管道输出结果,并且你想连接数组的数组,你可以使用reduce
let sorted_nums = ['1,3', '4,2']
.map(item => item.split(',')) // [['1', '3'], ['4', '2']]
.reduce((a, b) => a.concat(b)) // ['1', '3', '4', '2']
.sort() // ['1', '2', '3', '4']
这是一个函数,通过它可以连接多个数组
function concatNarrays(args) {
args = Array.prototype.slice.call(arguments);
var newArr = args.reduce( function(prev, next) {
return prev.concat(next) ;
});
return newArr;
}
的例子,
console.log(concatNarrays([1, 2, 3], [5, 2, 1, 4], [2,8,9]));
将输出
[1,2,3,5,2,1,4,2,8,9]
如果只有两个数组要连接,并且实际上需要追加其中一个数组,而不是创建一个新数组,则应该使用push或循环。
基准:https://jsperf.com/concat-small-arrays-vs-push-vs-loop/
对于使用ES2015 (ES6)的用户
你现在可以使用扩展语法来连接数组:
const arr1 = [0, 1, 2],
arr2 = [3, 4, 5];
const result1 = [...arr1, ...arr2]; // -> [0, 1, 2, 3, 4, 5]
// or...
const result2 = [...arr2, ...arr1]; // -> [3, 4, 5, 0, 1, 2]
新回答
对于多个数组和ES6的数组,使用
arr.flat();
例如:
const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = arr.flat();
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
这将适用于节点> 11和现代浏览器。
旧的答案
(把它留在这里,以防旧版本的节点需要它):
对于多个数组和ES6的数组,使用
Array.prototype.concat(...arr);
例如:
const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = Array.prototype.concat(...arr);
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
如果你有一个数组的数组,想要连接到一个数组的元素,尝试以下代码(要求ES2015):
let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = [];
for (let arr of arrOfArr) {
newArr.push(...arr);
}
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];
或者如果你喜欢函数式编程
let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = arrOfArr.reduce((result,current)=>{
result.push(...current);
return result;
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];
或者使用ES5语法更好,没有展开操作符
var arrOfArr = [[1,2,3,4],[5,6,7,8]];
var newArr = arrOfArr.reduce((result,current)=>{
return result.concat(current);
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];
如果你不知道不,这种方法很方便。数组的。
现在我们可以使用ES6 Spread组合多个数组。 不要使用concat()来连接数组,而是尝试使用spread语法将多个数组组合成一个扁平数组。 例如:
var a = [1,2];
var b = [3,4];
var c = [5,6,7];
var d = [...a, ...b, ...c];
// resulting array will be like d = [1,2,3,4,5,6,7]
用ES6缩短。
new Set([].concat(...Array));
这可以连接并唯一多个数组;
let Array = [ [“vue”,“巴别塔”,“npm”,“杯”,“mysql”,“少”,“laravel”), (“jquery”、“反应”,js, css, wordpress,“html”,“引导”), [“vue”,“巴别塔”,“npm”,“杯”,“mysql”,“少”,“laravel”), (‘角’,‘cms’,‘js’,‘css’,‘graphql’,‘nodejs ', ' php '], (“severless”、“无头”、“js”,“css”,“设计”,“ps”,“php”), ] const Boom = new Set([].concat(…数组)); //不需要 let dStr = "; Boom.forEach (e = > { dStr += e + ' '; }) document . write(下游); < div class = "结果" > < / div >
如果N个数组是从数据库中获得的,并且没有硬编码,i将使用ES6这样做
let get_fruits = [...get_fruits , ...DBContent.fruit];
用Push合并数组:
Const array1 = [2,7,4]; Const array2 = [3,5,9]; array1.push(…array2); console.log (array1)
使用Concat和Spread运算符: Const array1 = [1,2]; Const array2 = [3,4]; //方法1:Concat Const combined1 =[]。concat (array1 array2); //方法二:Spread Const combined2 =[…]array1……array2); console.log (combined1); console.log (combined2);
似乎正确答案在不同的JS引擎中有所不同。以下是我从ninjagecko的答案中链接的测试套件中得到的结果:
[] .concat。apply在Windows和Android的Chrome 83中最快,其次是reduce(慢56%); 循环concat在Mac的Safari 13中是最快的,其次是reduce(大约慢13%); reduce在iOS上的Safari 12中是最快的,其次是循环concat(慢40%); elementwise push在Windows上的Firefox 70中最快,其次是[].concat。应用(速度慢30%)。
最快的10倍是迭代数组,就像它们是一个数组一样,而不实际连接它们(如果可以的话)。
我很惊讶concat比push稍微快一点,除非测试不公平。
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']; const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's']; const arr3 = ['t', 'u', 'v', 'w']; const arr4 = ['x', 'y', 'z']; let start; // Not joining but iterating over all arrays - fastest // at about 0.06ms start = performance.now() const joined = [arr1, arr2, arr3, arr4]; for (let j = 0; j < 1000; j++) { let i = 0; while (joined.length) { // console.log(joined[0][i]); if (i < joined[0].length - 1) i++; else { joined.shift() i = 0; } } } console.log(performance.now() - start); // Concating (0.51ms). start = performance.now() for (let j = 0; j < 1000; j++) { const a = [].concat(arr1, arr2, arr3, arr4); } console.log(performance.now() - start); // Pushing on to an array (mutating). Slowest (0.77ms) start = performance.now() const joined2 = [arr1, arr2, arr3, arr4]; for (let j = 0; j < 1000; j++) { const arr = []; for (let i = 0; i < joined2.length; i++) { Array.prototype.push.apply(arr, joined2[i]) } } console.log(performance.now() - start);
如果你抽象它,你可以让不加入的迭代更干净,它仍然是原来的两倍:
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']; const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's']; const arr3 = ['t', 'u', 'v', 'w']; const arr4 = ['x', 'y', 'z']; function iterateArrays(arrays, onEach) { let i = 0; while (joined.length) { onEach(joined[0][i]); if (i < joined[0].length - 1) i++; else { joined.shift(); i = 0; } } } // About 0.23ms. let start = performance.now() const joined = [arr1, arr2, arr3, arr4]; for (let j = 0; j < 1000; j++) { iterateArrays(joined, item => { //console.log(item); }); } console.log(performance.now() - start);
你可以用这个-
let array2d = [[1, 2, 3], [5, 4], [7, 8]];
let array1d = array2d.reduce((merged, block) => {
merged.push(...block);
return merged;
}, []);
console.log(array1d); // [1, 2, 3, 5, 4, 7, 8]
或者从上面的一个答案中我喜欢这个-
let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log([].concat(...array2d)); // [1, 2, 3, 5, 4, 7, 8]
或者我发现的这个
let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log(array2d.join().split(',').map(Number); // [1, 2, 3, 5, 4, 7, 8]
你可以看看这个博客,在这里push()和concat()的性能进行了比较。此外,定制函数在特定场景下表现更好。
https://dev.to/uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki