1

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?

1
  • Could you use libraries such as loadash or ramda ? Commented Apr 10, 2018 at 19:43

9 Answers 9

2

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);

Sign up to request clarification or add additional context in comments.

4 Comments

Dang your second solution is almost identical to mine
@NicholasSiegmundt sorry, seems you submitted when I was writing it. Do you know what are the rules regarding this, should I delete it?
i know haha just thought it was funny. And no i do not. i'd just leave it.
They are both different approaches, in fact, this one is a little more creative for using Math.max, so upvoted for that!
2

You can use the function 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; }

1 Comment

it's just the approach to look at the outer parameter length and shape all other values and than use hard coded variable inside of mapping the values, which may be shorter in iteration but uses to much default values.
0

You can get rid of the temp var and the 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.

Comments

0

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);

1 Comment

What if the arrays have different lengths?
0

You could one line what's in the for loop like this:

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);

Comments

0

You could use ES6 and do something like this.

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));

Comments

0

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))

Comments

0

To achieve expected result use forEach method with array destructuring and it works for any array length

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

Comments

0

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; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.