简体   繁体   中英

Merge objects based on same key from different positions in an array

I have 2 arrays of 20 objects that I want to merge by name. The order of the names in each array is different, and the order is important and has to be left as is. This prevents me from a traditional sort and for loop approach. Basically, what I have is:

var tempList1 = [
   {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1},
   {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1},
   {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1},
...
];

var tempList2 = [
   {'manager':'Tom', 'x3':0, 'y3':10, 'x4':1, 'y4':1},
   {'manager':'Julie', 'x3':0, 'y3':90, 'x4':1, 'y4':1},
   {'manager':'John', 'x3':0, 'y3':50, 'x4':1, 'y4':1},
...
];

Notice that John is at index 0 in tempList1 but is at index 2 at tempList2 . When I tried:

          for (var k = 0; k < managerList.length; k++) {
            let merged = {...tempList1[k],...tempList2[k]}
            combinedList.push(merged);
          }

I was making the mistake of assuming the order was the same in each array -- when its not.

End result should be:

var combinedList = [
    {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1, 'x3':0, 'y3':50, 'x4':1, 'y4':1},
    {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1, 'x3':0, 'y3':10, 'x4':1, 'y4':1},
    {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1, 'x3':0, 'y3':90, 'x4':1, 'y4':1}
];

Question

How can I merge objects so that only objects when the same manager value are merged with each other in my array?

From one of the lists, create an object indexed by manager . Then, when iterating over the other list, just lookup the same manager property and merge:

 var tempList1 = [ {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1}, {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1}, {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1} ]; var tempList2 = [ {'manager':'Tom', 'x3':0, 'y3':10, 'x4':1, 'y4':1}, {'manager':'Julie', 'x3':0, 'y3':90, 'x4':1, 'y4':1}, {'manager':'John', 'x3':0, 'y3':50, 'x4':1, 'y4':1} ]; const list1ByManager = tempList1.reduce((a, item) => { a[item.manager] = item; return a; }, {}); const combined = tempList2.map((item2) => ({ ...list1ByManager[item2.manager], ...item2 })); console.log(combined); 

As you need to have one case per management, I transformed your array to an object with the manager's name as the key and then transformed to an array of objects again

 var tempList1 = [ {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1}, {'manager':'Tom', 'x3':0, 'y3':0, 'x4':1, 'y4':1}, {'manager':'Julie', 'x1':0, 'y1':0, 'x2':1, 'y2':1}, ].reduce(function(result, obj) { result[obj.manager] = obj return result }, {}); console.log(tempList1) var tempList2 = [ {'manager':'Tom', 'x3':0, 'y3':0, 'x4':1, 'y4':1}, {'manager':'Julie', 'x3':0, 'y3':0, 'x4':1, 'y4':1}, {'manager':'John', 'x3':0, 'y3':0, 'x4':1, 'y4':1}, ].reduce(function(result, obj) { result[obj.manager] = obj return result }, {}); var temp = [] for (var key in tempList1) { temp.push({ ...tempList1[key], ...tempList2[key] }) } console.log(temp) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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