-1

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. ..........................................................................................................................................................

1 Answers1

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)
Steve Tomlin
  • 3,391
  • 3
  • 31
  • 63