3

I am trying to merge two arrays of objects together.

I have presorted the arrays of objects so that they match, I just need to push the properties across each object in both arrays.

I think lodash would give me a cleaner solution than a double for loop, or should I just do a vanilla JS solution?

Example of two arrays:

[
    {
        provider: 'foo',
        title: 'Title1'
    },
    {
        provider: 'bar',
        title: 'Title2'
    }
]

[
    {
        all: '0',
        novelty: '24'
    },
    {
        all: '4',
        novelty: '12'
    }
]

It should return:

[
    {
        provider: 'foo',
        title: 'Title1',
        all: '0',
        novelty: '24'
    },
    {
        provider: 'bar',
        title: 'Title2',
        all: '4',
        novelty: '12'
    }
]
4
  • Use the tools you have in hand, if lodash is loaded, use it. Commented Oct 29, 2016 at 19:59
  • Just to nitpick, these are JS arrays, but not valid JSON. Commented Oct 29, 2016 at 19:59
  • 1
    Fair. Sorry, the objects are returned from an API call, but that is irrelevant for the problem :) Commented Oct 29, 2016 at 20:26
  • You're right ;) Commented Oct 29, 2016 at 20:34

3 Answers 3

2

Without lodash you can use Array.prototype.map() and Object.assign() (or angular.merge() if assign is not supported by the target browsers):

var arr1 = [{
      provider: 'foo',
      title: 'Title1'
    }, {
      provider: 'bar',
      title: 'Title2'
    }];

    var arr2 = [{
      all: '0',
      novelty: '24'
    }, {
      all: '4',
      novelty: '12'
    }];

    var result = arr1.map(function(item, index) {
      return Object.assign({}, item, arr2[index]);
    });

    console.log(result);

If you want to use lodash use _.zipWith() with _.assign():

var arr1 = [{
  provider: 'foo',
  title: 'Title1'
}, {
  provider: 'bar',
  title: 'Title2'
}];

var arr2 = [{
  all: '0',
  novelty: '24'
}, {
  all: '4',
  novelty: '12'
}];

var result = _.zipWith(arr1, arr2, function(a, b) {
  return _.assign({}, a, b);
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>

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

2 Comments

This worked (no lodash). I think I'll see if I can figure out how to inject lodash into the project in case I might need it (this is an Angular project), but I have decided for now to move on since it's not entirely trivial.
With the array methods like map, reduce, forEach, every, some, etc... and the utilities in angular, merge for example, you hardly need lodash. If you want to include lodash, you can do so as a global or wrap it in an angular service.
2

You can do this with ES6:

data1.map( (obj, i) => Object.assign({}, obj, data2[i]) )

var data1 = [{
        provider: 'foo',
        title: 'Title1'
    }, {
        provider: 'bar',
        title: 'Title2'
    }];
var data2 = [{
        all: '0',
        novelty: '24'
    }, {
        all: '4',
        novelty: '12'
    }];

var merged = data1.map( (obj, i) => Object.assign({}, obj, data2[i]) );

console.log(merged);

1 Comment

Thanks for letting me know ;-)
1

So far the other answers to this question are sub-optimal in that they ignore your stated condition that the input arrays are pre-sorted. AFAIK lodash has no pre-built method for merging sorted arrays, but a Google search for "merge sorted arrays" will reveal lots of pseudocode to emulate.

For example, here's a JS implementation of http://www.algolist.net/Algorithms/Merge/Sorted_arrays:

const mergeSortedArraysBy = (array1, array2, iteratee) => {
    const mergedArray = [];
    let i = 0;
    let j = 0;
    while (i < array1.length && j < array2.length) {
        if (iteratee(array1[i]) <= iteratee(array2[j])) {
            mergedArray.push(array1[i]);
            i++;
        } else {
            mergedArray.push(array2[j]);
            j++;
        }
    }
    if (i < array1.length) {
        for (let p = i; p < array1.length; p++) {
            mergedArray.push(array1[p]);
        }
    } else {
        for (let p = j; p < array2.length; p++) {
            mergedArray.push(array2[p]);
        }
    }
    return mergedArray;
};

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.