3

I want to merge 2 object with same key, value from 2 array, something like this:

var arr1 = [
    { a: "a", 1: 1, 2: 2 },
    { a: "b", 1: 1, 2: 3 }
];

var arr2 = [
    { a: "a", 3: 123 },
    { a: "b", 3: 4411 }
];

var arr3 = _.map(arr1, function(a1) {
    var a3 = {};

    _.map(arr2, function(a2) {
        if (a1.a == a2.a) {
            a3 = _.extend(a1, a2);
        }
    })

    return a3
});

result:

arr3 = [ 
  { '1': 1, '2': 2, '3': 123, a: 'a' },
  { '1': 1, '2': 3, '3': 4411, a: 'b' } 
]

Does it look stupid? Are there any others ways to do this? Thanks for reading.

5
  • 1
    is your solution working or not?What is the question? Commented Sep 23, 2017 at 6:14
  • it worked, but i think there are some other better ways to do that with some library. (im not tested with big array length yet) Commented Sep 23, 2017 at 6:17
  • While posting question please be more specific. For example mention which JavaScript library you are used. It will help people to investigate on the similar kind of library your are used. Commented Sep 23, 2017 at 6:40
  • what means same key? same index or same key a? Commented Sep 23, 2017 at 7:30
  • Possible duplicate of How to use Lodash to merge two collections based on a key? Commented Sep 23, 2017 at 8:07

2 Answers 2

8

Use a lodash chain to concat the arrays, group similar objects, and then merge each group to a single object:

var arr1 = [{ a: "a", 1: 1, 2: 2 }, { a: "b", 1: 1, 2: 3 }];
var arr2 = [{ a: "a", 3: 123 }, { a: "b", 3: 4411 }];

var result = _(arr1)
  .concat(arr2) // concat the 2nd array
  .groupBy('a') // group by the identical key
  .map(_.spread(_.curry(_.merge, {}))) // left currey merge to to create a new empty object, and spread the group as parameters
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

With ES6 you can use Array#reduce to collect the similar objects in a Map, then get the Map#values iterator, and use the spread syntax to convert to an array:

const arr1 = [{ a: "a", 1: 1, 2: 2 }, { a: "b", 1: 1, 2: 3 }];
const arr2 = [{ a: "a", 3: 123 }, { a: "b", 3: 4411 }];

const result = [...arr1.concat(arr2) // concat the arrays
  .reduce((m, o) => m.set(o.a, Object.assign(m.get(o.a) || {}, o)), // use a map to collect similar objects
  new Map()
).values()]; // get the values iterator of the map, and spread into a new array
  
console.log(result);

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

4 Comments

Lodash way is working. ES6 version is not working though.
@Ajinkya - have you tried running the snippets? If so, what browser are you using?
My bad. I did not replace property 'a' for es6 snippet. Both the snippets are working. Which one do you recommend to use considering the performance?
@Ajinkya - I don't really know to tell you the truth. If the amount of items is small, it doesn't really matter. If the amount is huge, you should with lodash, since spread is not stack safe. You'll need to profile it.
4

you can do

var arr1 = [
    { a: "a", 1: 1, 2: 2 },
    { a: "b", 1: 1, 2: 3 }
];

var arr2 = [
    { a: "a", 3: 123 },
    { a: "b", 3: 4411 }
];

let result = arr1.map((e) => {
    for(let element of arr2){
        if(e.a == element.a) Object.assign(e, element);
    }
    return e;
});
console.log(result);

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.