Home > database >  JS - nested for loops - compare 2 arrays by key, return 4 new arrays, matches & unmatches from each
JS - nested for loops - compare 2 arrays by key, return 4 new arrays, matches & unmatches from each

Time:01-26

Made a demo for the question -

The arrays -

const arr1 = [
  {
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "NYC"
  },
  {
    key: "kosta|28",
    name: "kosta",
    age: 28,
    city: "NYC"
  }
];

const arr2 = [
  {
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "TLV"
  },
  {
    key: "simon|24",
    name: "simon",
    age: 24,
    city: "NYC"
  },
  {
    key: "david|22",
    name: "david",
    age: 22,
    city: "NYC"
  }
];

Empty arrays for assigning -

let arr1Match = [];
let arr1Unmatch = [];

let arr2Match = [];
let arr2Unmatch = [];

For loop -

for (let i = 0; i < arr1.length; i  ) {
for (let j = 0; j < arr2.length; j  ) {
    const arr1Key = arr1[i].key;
    const arr2Key = arr2[j].key;

    if (arr1Key === arr2Key) {
        arr1Match.push(arr1[i])
        arr2Match.push(arr2[i])
    } else {
        arr1Unmatch.push(arr1[i])
        arr2Unmatch.push(arr2[i])
    }
}

}

What I'm outputing -

console.log(arr1Match);
console.log(arr1Unmatch);

console.log(arr2Match);
console.log(arr2Unmatch);

Output -

arr1Match: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }]

arr1Unmatch: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }, { "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }]

arr2Match: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }]

arr2Unmatch: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }, { "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }]

The desired output -

arr1Match: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }]

arr1Unmatch: [{ "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }]

arr2Match: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }]

arr2Unmatch: [{ "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "david|22", "name": "david", "age": 22, "city": "NYC" }]

I need the loops to go through all values in the arrays and return all the matches and unmatches from each. And I need to assing property from arr2 to arr1 if there is a match

CodePudding user response:

You could get the common keys and take the partition of each array.

const
    match = (a, b, fn) => {
        const 
            getCommon = (a, b) => {
                const c = {};
                a.forEach(o => c[fn(o)] = false);
                b.forEach(o => c[fn(o)] = fn(o) in c);
                return c;
            };
            common = getCommon(a, b, fn),
            getParts = (a, c) => a.reduce((r, o) => (r[ !common[fn(o)]].push(o), r), [[], []]);
            
        return [
            getParts(a, common),
            getParts(b, common)
        ];
    }
    array1 = [{ key: "daniel|21", name: "daniel", age: 21, city: "NYC" }, { key: "kosta|28", name: "kosta", age: 28, city: "NYC" }],
    array2 = [{ key: "daniel|21",name: "daniel", age: 21, city: "TLV" }, { key: "simon|24", name: "simon", age: 24, city: "NYC" }, { key: "david|22", name: "david", age: 22, city: "NYC" }],
    [
        [arr1Match, arr1Unmatch],
        [arr2Match, arr2Unmatch]
    ] = match(array1, array2, o => o.key);

console.log(arr1Match);
console.log(arr1Unmatch);

console.log(arr2Match);
console.log(arr2Unmatch);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

I'm not quite sure I understand your question, is this the result you want?

const arr1 = [{
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "NYC"
  },
  {
    key: "kosta|28",
    name: "kosta",
    age: 28,
    city: "NYC"
  }
];

const arr2 = [{
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "TLV"
  },
  {
    key: "simon|24",
    name: "simon",
    age: 24,
    city: "NYC"
  },
  {
    key: "david|22",
    name: "david",
    age: 22,
    city: "NYC"
  }
];

const arr1Keys = arr1.map(a => a.key);
const arr2Keys = arr2.map(a => a.key);
const keys = [...arr1Keys, ...arr2Keys];
const repeat = keys.filter((o, i) => keys.indexOf(o) !== i);
const unique = [...new Set(keys)].filter(o => !repeat.includes(o));

const arr1Match = arr1.filter(a => repeat.includes(a.key));
const arr1Unmatch = arr1.filter(a => unique.includes(a.key));
const arr2Match = arr2.filter(a => repeat.includes(a.key));
const arr2Unmatch = arr2.filter(a => unique.includes(a.key));
const arr1Match2 = arr1Match.map(a1 => {
  let obj = arr2Match.find(a2 => a2.key == a1.key);
  return {...obj, city: obj.city}
});
const arr1Match3 = arr1Match.map(a1 => arr2Match.find(a2 => a2.key == a1.key));

console.log('arr1Match before', JSON.stringify(arr1Match));
console.log('arr1Match overwrite city', JSON.stringify(arr1Match2));
console.log('arr1Match overwrite all', JSON.stringify(arr1Match3));
console.log('arr1Unmatch', JSON.stringify(arr1Unmatch));
console.log('arr2Match', JSON.stringify(arr2Match));
console.log('arr2Unmatch', JSON.stringify(arr2Unmatch));

  •  Tags:  
  • Related