简体   繁体   English

将对象数组合并为一个对象数组

[英]Merge arrays of objects into one array of objects

OK so I've already actually figured out a solution to my problem, but it's ugly, and I'm sure there's a much more elegant way to do it. 好的,所以我实际上已经找到了解决问题的方法,但这很丑陋,而且我敢肯定有一种更优雅的方法可以解决此问题。

Say I've got two arrays (which I know to be of the same length), of simple objects, like this: 假设我有两个简单对象的数组(我知道它们的长度相同),如下所示:

var aVals = [{a: 1}, {a: 2}, {a: 3}];

var bVals = [{b: 4}, {b: 5}, {b: 6}];

What I want to do is squash these two arrays together, so to speak, to get something that looks like this: 我想要做的是将这两个数组压缩在一起,可以这么说:

var allVals = [{a: 1, b: 4},{a: 2, b: 5},{a: 3, b: 6}];

Granted, I can do that like this: 当然,我可以这样做:

var uglySolution = [];

for(var i = 0; i < aVals.length; i++){
  var temp = [];
  temp.push(aVals[i]);
  temp.push(bVals[i]);
  uglySolution.push(Object.assign({}, ...temp)); 
}

console.log(uglySolution);

But there's got to be a better way! 但是必须有更好的方法! Right? 对?

*Bonus quest: and what if I couldn't be sure both arrays were the same length? *奖金追求:如果我不确定两个数组的长度相同怎么办?

You can use the function Array.from . 您可以使用Array.from函数。

  • Check for the max length. 检查最大长度。
  • Check for object at a specific index for both arrays. 检查两个数组的特定索引处的对象。

 var aVals = [{a: 1}, {a: 2}, {a: 3}]; var bVals = [{b: 4}, {b: 5}, {b: 6}, {a: 4}]; var merge = Array.from({length: Math.max(aVals.length, bVals.length)}, (_, i) => { return Object.assign({}, bVals[i] || {}, aVals[i] || {}); }); console.log(merge) 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

If you have arrays of the same length it's simple: 如果长度相同的数组很简单:

 var aVals = [{a: 1}, {a: 2}, {a: 3}]; var bVals = [{b: 4}, {b: 5}, {b: 6}]; var result = aVals.map((el, i) => Object.assign({}, el, bVals[i])); console.log(result); 

To do it with different array length I'd do it like this: 要使用不同的数组长度来做到这一点,我会这样做:

 var aVals = [{a: 1}, {a: 2}]; var bVals = [{b: 4}, {b: 5}, {b: 6}]; var result = []; var length = Math.max(aVals.length, bVals.length); for (var i = 0; i < length; i++) { result.push(Object.assign({}, aVals[i] || {}, bVals[i] || {})); } console.log(result); 

You can get rid of the temp var and the uglySolution var. 您可以摆脱temp var和uglySolution var。

for (var i = 0; i < bVals.length; i++) {
    aVals.push(bVals.pop())
}
console.log(aVals);

This simplifies it into one var being used and only a small loop. 这将其简化为仅使用一个变量和一个小的循环。

You could one line what's in the for loop like this: 您可以像这样在for循环中一行:

var uglySolution = [];

for(var i = 0; i < aVals.length; i++){
  uglySolution.push(Object.assign({}, aVals[i], bVals[i]))
}

console.log(uglySolution);

Assuming both arrays are the same size. 假设两个数组的大小相同。

If they are NOT the same size, do this: 如果它们的大小不相同,请执行以下操作:

var uglySolution = [];
var longestLength =  aVals.length >  bVals.length ? aVals.length : bVals.length;

for(var i = 0; i < longestLength; i++){
  uglySolution.push(Object.assign({}, aVals[i] || {} , bVals[i] || {}))
}

console.log(uglySolution);

This would be a bit better, I think. 我认为这会好一些。

 var aVals = [{a: 1}, {a: 2}, {a: 3}]; var bVals = [{b: 4}, {b: 5}, {b: 6}]; var result = aVals.map((val, index) => Object.assign(val, bVals[index])); console.log(result); 

I think your solution is fine. 我认为您的解决方案很好。 It works and it's readable, so I'd say there's no need for a "better solution". 它有效并且可读性强,所以我说不需要“更好的解决方案”。 However, if you're looking for something shorter, you can definitely compress your code a bit. 但是,如果您要查找更短的内容,则可以肯定地压缩一下代码。

Here's one way of doing so that uses array destructuring and object spread. 这是使用数组解构和对象散布的一种方法。 Just take the longer array, and map each of it's items to the combo of that item and the item in the same position in the other array. 只需采用更长的数组,然后将其每个项目映射到该项目的组合以及另一个数组中相同位置的项目。

 var aVals = [{a: 1}, {a: 2}, {a: 3}]; var bVals = [{b: 4}, {b: 5}, {b: 6}, {b: 7}]; // var allVals = [{a: 1, b: 4},{a: 2, b: 5},{a: 3, b: 6}]; function zipArrays(arr1, arr2) { // Swap if arr2 is longer, so that on the next line, arr1 is always longer if (arr2.length > arr1.length) [arr1, arr2] = [arr2, arr1]; return arr1.map((o, i) => ({...o, ...arr2[i]})); } console.log(zipArrays(aVals, bVals)) 

You could use ES6 and do something like this. 您可以使用ES6并执行类似的操作。

 var aVals = [{ a: 1 }, { a: 2 }, { a: 3 }]; var bVals = [{ b: 4 }, { b: 5 }, { b: 6 }, { b: 7 }]; const mergeArrays = (obj1, obj2) => { if (obj1.length > obj2.length) { [obj1, obj2] = [obj2, obj1]; } const output = obj1.map((value, index) => { return { ...value, ...obj2[index] }; }); return output.concat(obj2.slice(obj1.length, obj2.length)); } console.log(mergeArrays(aVals, bVals)); 

You could collect all arrays with the data and use an approach which works for an arbitrary count of given arrays with objects and length. 您可以使用数据收集所有数组,并使用一种方法来对带有对象和长度的给定数组进行任意计数。

 var merge = (r, a) => (a.forEach((o, i) => Object.assign(r[i] = r[i] || {}, o)), r) aVals = [{ a: 1 }, { a: 2 }, { a: 3 }], bVals = [{ b: 4 }, { b: 5 }, { b: 6 }], result = [aVals, bVals].reduce(merge, []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

To achieve expected result use forEach method with array destructuring and it works for any array length 要获得预期的结果,请使用带数组解构的forEach方法,该方法适用于任何数组长度

 var aVals = [{a: 1}, {a: 2}]; var bVals = [{b: 4}, {b: 5}, {b: 6}]; var allVals = [] var func = (arr) => arr.forEach(function(element,index) { allVals[index] = {...allVals[index],...arr[index]} }); func(aVals); func(bVals); console.log(allVals) 

code sample - https://codepen.io/pen/?editors=1010 代码示例-https: //codepen.io/pen/?editors=1010

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM