-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: "NYC",
    address: 'E. 43'
  },
  {
    name: "simon",
    age: 24,
    city: "NYC",
    address: 'E. 43'
  },
  {
    name: "david",
    age: 22,
    city: "NYC",
    address: 'E. 43'
  },
  {
    name: "kosta",
    age: 28,
    city: "NYC",
    address: 'E. 43'
  }
];

Getting keys for the arrays -

const arr1Map: ReadonlyMap<string, string | undefined> = new Map(
    arr1.map(
        ({
            name, age, city, address
        }) => [
            `${name}|${age}|${city}`,
            address
        ]
    )
);

const arr2Map: ReadonlyMap<string, string | undefined> = new Map(
    arr2.map(
        ({
            name, age, city, address
        }) => [
            `${name}|${age}|${city}`,
            address
        ]
    )
);

Empty arrays -

let arr1Match: I[] = []
let arr1Unmatch: I[] = []
let arr2Match: I[] = []
let arr2Unmatch: I[] = []

What I need to do now is to campare all values in arr1 to arr2, if there is a match, store the match from arr1 in arr1Match and the match from arr2 in arr2Match. If there is an Unmatch I need to store the unmatch arr1 in arr1Unmatch and the unmatch from arr2 in arr2Unmatch. And if there is a match I need to store the address from arr2 into arr1.

The desierd output -

arr1Match: [{ name: "daniel", age: 21, city: "NYC", address: 'E. 43' }, { name: "kosta", age: 28, city: "NYC", address: 'E. 43' } ]

arr2Match: [{ name: "daniel", age: 21, city: "NYC", address: 'E. 43' }, { name: "kosta", age: 28, city: "NYC", address: 'E. 43' }]

arr1Unmatch: [{ name: "yoav", age: 28, city: "NYC" }]

arr2Unmatch: [{ name: "simon", age: 24, city: "NYC", address: 'E. 43' }, { name: "david", age: 22, city: "NYC", address: 'E. 43' }]

heyheyhey
  • 35
  • 1
  • 7

1 Answers1

0

The answer depends on some questions about your needs: What constitutes a match? If there's different data between the matches, what should be put in the match array? Should the arrays point to the original objects, or to copies of them?
Also, it looks like there is no difference between arr1Match and arr2Match, so those can be combined into one

Either way the solution would be to iterate over one array, and search for a match in the other array for every value. Any item that doesn't match will go to the unmatch arrays

// Replace with real match logic
const isMatch = <T>(a: T, b: T) => Math.random() < 0.5;

const getMatches = <T>(arrOne: T[], arrTwo: T[]) => {
  const matches: T[] = [];
  const arrOneUnmatches: T[] = [];
  let arrTwoUnmatches: T[];

  // Copying for comfortability's sake
  const arrTwoCopy = [...arrTwo];

  arrOne.forEach(item => {
    // Find a match in array two
    const arrTwoMatchIndex = arrTwoCopy.findIndex(arrTwoItem => isMatch(item, arrTwoItem));
    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 }
}
Jason
  • 632
  • 1
  • 5
  • 17
  • There is no assigning of the `address` from `arr2` to `arr1`. Desired output - arr1Match: `[{ name: "daniel", age: 21, city: "NYC", address: 'E. 43' }, { name: "kosta", age: 28, city: "NYC", address: 'E. 43' } ]` Current output - `[ { "name": "daniel", "age": 21, "city": "NYC" }, { "name": "kosta", "age": 28, "city": "NYC" } ]` – heyheyhey Jan 26 '22 at 11:30
  • @heyheyhey ok? so change it to match your needs. I gave you pretty much all you need – Jason Jan 26 '22 at 13:11