'JS - assing values between arrays when comparing for matches and unmatches
Interface -
interface I {
name: string;
age: number;
city: string;
address?: string;
}
Arrays -
const arr1: I[] = [
{
name: "daniel",
age: 21,
city: 'NYC'
},
{
name: "kosta",
age: 28,
city: "NYC"
},
{
name: "yoav",
age: 28,
city: "NYC"
}
];
const arr2: I[] = [{
name: "daniel",
age: 21,
city: "DWA",
address: 'E. 43'
},
{
name: "simon",
age: 24,
city: "EWQ",
address: 'E. 43'
},
{
name: "david",
age: 22,
city: "VVG",
address: 'E. 43'
},
{
name: "kosta",
age: 28,
city: "DER",
address: 'E. 43'
}
];
Function that get matches and unmatches -
const isMatch = (a: string, b: string) => Math.random() < 0.5;
const getMatches = (arrOne: I[], arrTwo: I[]) => {
const matches: I[] = [];
const arrOneUnmatches: I[] = [];
let arrTwoUnmatches: I[];
// Copying for comfortability's sake
const arrTwoCopy = [...arrTwo];
arrOne.forEach((item) => {
// Find a match in array two
const arrTwoMatchIndex = arrTwoCopy.findIndex(({ name, age }) => isMatch(item.name + '/' + item.age, name + '/' + age));
if (arrTwoMatchIndex) {
matches.push(item);
// Remove it from arrTwoCopy, to maintain arrTwoUnmatches
arrTwoCopy.splice(arrTwoMatchIndex, 1);
} else {
// No match = go to arrOneUnmatches
arrOneUnmatches.push(item);
}
})
// Anyone left in arrTwoCopy didn't match anyone in arrOne, so they have no match
arrTwoUnmatches = arrTwoCopy;
return { matches, arrOneUnmatches, arrTwoUnmatches }
}
Current output -
console.log(getMatches(arr1, arr2)).
"matches": [
{
"name": "kosta",
"age": 28,
"city": "NYC"
},
{
"name": "yoav",
"age": 28,
"city": "NYC"
}
],
"arrOneUnmatches": [
{
"name": "daniel",
"age": 21,
"city": "NYC"
}
],
"arrTwoUnmatches": [
{
"name": "daniel",
"age": 21,
"city": "NYC",
"address": "E. 43"
},
{
"name": "kosta",
"age": 28,
"city": "DER",
"address": "E. 43"
}
]
Desired output -
"matches": [
{
"name": "daniel",
"age": 21,
"city": "NYC",
"address": 'E. 43'
},
{
"name": "kosta",
"age": 28,
"city": "NYC",
"address": 'E. 43'
}
],
"arrOneUnmatches": [
{
"name": "yoav",
"age": 28,
"city": "NYC"
}
],
"arrTwoUnmatches": [
{
name: "simon",
age: 24,
city: "NYC",
address: 'E. 43'
},
{
name: "david",
age: 22,
city: "NYC",
address: 'E. 43'
}
]
Right now I don't get the matches and unmatches right, I don't know why. and I want to assing the address from arr2 to arr1 if there is a match.
..........................................................................................................................................................
Solution 1:[1]
const getMatches = (arr1, arr2, keysToMatch) => {
const getMatch = (obj1, arr, fnMatch) => arr.find(obj2 => keysToMatch.every(key => fnMatch(key, obj1, obj2)))
const matches = arr1.reduce((acc, item1) => {
const match = getMatch(item1, arr2, (key, obj1, obj2) => obj1[key] === obj2[key])
if (match) {
acc.push({...item1, ...match})
}
return acc
}, [])
const arr1NonMatches = arr1.reduce((acc, item1) => {
if (getMatch(item1, arr2, (key, obj1, obj2) => obj1[key] !== obj2[key])) {
acc.push(item1)
}
return acc
}, [])
const arr2NonMatches = arr2.reduce((acc, item2) => {
if (getMatch(item2, arr1, (key, obj2, obj1) => obj2[key] !== obj1[key])) {
acc.push(item2)
}
return acc
}, [])
return {matches, arr1NonMatches, arr2NonMatches}
}
const arr1 = [
{
name: "daniel",
age: 21,
city: 'NYC'
},
{
name: "kosta",
age: 28,
city: "NYC"
},
{
name: "yoav",
age: 28,
city: "NYC"
}
];
const arr2 = [{
name: "daniel",
age: 21,
city: "DWA",
address: 'E. 43'
},
{
name: "simon",
age: 24,
city: "EWQ",
address: 'E. 43'
},
{
name: "david",
age: 22,
city: "VVG",
address: 'E. 43'
},
{
name: "kosta",
age: 28,
city: "DER",
address: 'E. 43'
}
];
const objMatches = getMatches(arr1, arr2, ['name', 'age'])
console.log(objMatches)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
