3

I am trying to merge together the array1 and array2 by matching on the sku. But if a sku has multiple (like 62617802), I want to keep both value from array1 and array2, like, first sku (62617802) will merge with first sku (62617802) of array2 and so on.

Input Note: If the SKU is duplicate (like twice or thrice or so on) in array1 it would be also same on array2. Also if array1 count is 5 then array2 count also 5.

var array1 = [
    {
        "sku": "35189424",
        "price": 107800,
        "isNew": false,
        "name": "Product Title A"
    },
    {
        "sku": "62617802",  // duplicate
        "price": 107800,
        "isNew": false,
        "name": "Product Title D"
    },
    {
        "sku": "GRP00437",
        "price": 107800,
        "isNew": false,
        "name": "Product Title B"
    },
    {
        "sku": "62617802",      // duplicate
        "price": 107800,
        "isNew": false,
        "name": "Product Title D"
    },
    {
        "sku": "35189432",
        "price": 107800,
        "isNew": false,
        "name": "Product Title YZ"
    }

];

var array2 = [
    {
        "sku": "35189424",
        "Url": "https://......",
        "rating": 2,
        "status": 0
    },
    {
        "sku": "62617802",  // duplicate
        "Url": "https://......",
        "rating": 5,
        "status": 1
    },
    {
        "sku": "GRP00437",
        "Url": "https://......",
        "rating": 2,
        "status": 1
    },
    {
        "sku": "35189432",
        "Url": "https://......",
        "rating": 3,
        "status": 1
    },
    {
        "sku": "62617802",  // duplicate
        "Url": "https://......",
        "rating": 5,
        "status": 1
    }
];


var outputArray = [
    {
        "sku": "35189424",
        "price": 107800,
        "isNew": false,
        "name": "Product Title A",
        "Url": "https://......",
        "rating": 2,
        "status": 0
    },
    {
        "sku": "62617802",      // duplicate
        "price": 107800,
        "isNew": false,
        "name": "Product Title D",
        "Url": "https://......",
        "rating": 5,
        "status": 1
    },
    {
        "sku": "GRP00437",
        "price": 107800,
        "isNew": false,
        "name": "Product Title B",
        "Url": "https://......",
        "rating": 2,
        "status": 1
    },
    {
        "sku": "62617802",  // duplicate
        "price": 107800,
        "isNew": false,
        "name": "Product Title D",
        "Url": "https://......",
        "rating": 5,
        "status": 1
    },
    {
        "sku": "35189432",
        "price": 107800,
        "isNew": false,
        "name": "Product Title YZ",
        "Url": "https://......",
        "rating": 3,
        "status": 1
    }
];
Daniel Smith
  • 1,626
  • 3
  • 29
  • 59

5 Answers5

3

You could take an object for grouping same sku and shift objects for keeping the same order fro merging.

const
    array1 = [{ sku: "35189424", price: 107800, isNew: false, name: "Product Title A" }, { sku: "62617802", price: 107800, isNew: false, name: "Product Title D" }, { sku: "GRP00437", price: 107800, isNew: false, name: "Product Title B" }, { sku: "62617802", price: 107800, isNew: false, name: "Product Title D" }, { sku: "35189432", price: 107800, isNew: false, name: "Product Title YZ" }],
    array2 = [{ sku: "35189424", Url: "https://......", rating: 2, status: 0 }, { sku: "62617802", Url: "https://......", rating: 5, status: 1 }, { sku: "GRP00437", Url: "https://......", rating: 2, status: 1 }, { sku: "35189432", Url: "https://......", rating: 3, status: 1 }, { sku: "62617802", Url: "https://......", rating: 5, status: 1 }],
    skus = array2.reduce((r, o) => ((r[o.sku] = r[o.sku] || []).push(o), r), { }),
    result = array1.map(o => ({ ...o, ...skus[o.sku].shift() }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • if I wanted to keep array1 is a main? – Daniel Smith Sep 25 '20 at 16:45
  • looks like your ??= getting eeor for me. – Daniel Smith Sep 25 '20 at 16:54
  • it was a [logical nullish assignment `??=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment). please see edit. – Nina Scholz Sep 25 '20 at 16:59
  • If the array2 length is greater than array1, does this work? – Daniel Smith Sep 26 '20 at 07:55
  • array1 is my base array, and if array2 having more data greater than array1 will it work? – Daniel Smith Sep 26 '20 at 07:57
  • do you want to add the rest of the second array to the result? or what should happen with it? do you have an example? – Nina Scholz Sep 26 '20 at 07:57
  • Like on array1 sky 62617802 have three times, then the output will find first 62617802 on array2 and then second 62617802 on the second array 2.. so on. If the sku is not found on array2, the output will remove this... let me give you more example – Daniel Smith Sep 26 '20 at 08:02
  • if `array2` has more items than `array1`, leftover items are removed. what should happen with the leftover items from `array2`? – Nina Scholz Sep 26 '20 at 08:08
  • in that case, will keep only how much on array1 count. The rest of the other items from array2 (leftover) does not require. Here I had explained a bit please have a look. https://jsfiddle.net/bikash336/h8gvyduf/33/ – Daniel Smith Sep 26 '20 at 08:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222106/discussion-between-nina-scholz-and-daniel-smith). – Nina Scholz Sep 26 '20 at 08:29
  • I have an another JS question, It would be helpfull if you could take a look there https://stackoverflow.com/questions/68737245/javascript-add-line-break-after-specefic-character-count-with-maximum-line-lim – Daniel Smith Aug 11 '21 at 07:14
0

There are many ways to do this, here is one:

both = array1.concat(array2);
const merged = {};
both.forEach(entry => {
  !merged[entry.sku] && (merged[entry.sku] = {});
  Object.assign(merged[entry.sku], entry);
});
const result = Object.values(merged);
console.log(result);
Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
  • I have an another JS question, It would be helpfull if you could take a look there https://stackoverflow.com/questions/68737245/javascript-add-line-break-after-specefic-character-count-with-maximum-line-lim – Daniel Smith Aug 11 '21 at 07:14
0

So basically you need to merge items having the same indices?

var array1 = [{"sku":"35189424","price":107800,"isNew":false,"name":"Product Title A"},{"sku":"62617802","price":107800,"isNew":false,"name":"Product Title D"},{"sku":"GRP00437","price":107800,"isNew":false,"name":"Product Title B"},{"sku":"62617802","price":107800,"isNew":false,"name":"Product Title D"},{"sku":"35189432","price":107800,"isNew":false,"name":"Product Title YZ"}];

var array2 = [{"sku":"35189424","Url":"https://......","rating":2,"status":0},{"sku":"62617802","Url":"https://......","rating":5,"status":1},{"sku":"GRP00437","Url":"https://......","rating":2,"status":1},{"sku":"35189432","Url":"https://......","rating":3,"status":1},{"sku":"62617802","Url":"https://......","rating":5,"status":1}];



console.log(array1.map((item, i) => ({...item, ...array2[i]})))
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
  • where you map by key (SKU)? – Daniel Smith Sep 25 '20 at 16:17
  • I have an another JS question, It would be helpfull if you could take a look there https://stackoverflow.com/questions/68737245/javascript-add-line-break-after-specefic-character-count-with-maximum-line-lim – Daniel Smith Aug 11 '21 at 07:14
0
let result = array1.reduce((acc, cv) => {
  var objj = array2.filter((obj) => obj.sku === cv.sku);
  if (!acc.some((item) => item.sku === cv.sku)) {
    let p = Object.assign({}, ...[cv], ...objj);
    acc.push(p);
  }
  return acc;
}, []);
SathwikaRao
  • 133
  • 1
  • 8
0

I borrowed ideas from @Nina, but with simpler constructs.

const d1 = {};
const d2 = {};
const outputArray = [];

const addElement = (d, el) => {
  if (!d[el.sku]) d[el.sku] = [el];
  else d[el.sku].push(el)
};
array1.forEach(el => addElement(d1, el));
array2.forEach(el => addElement(d2, el));

for (let k in d1) {
  const res = d1[k].map((el, ind) => ({...el, ...d2[k][ind]}));
  outputArray.push(...res);
}

console.log(outputArray);