Home > Enterprise >  how to find objects that match specific keys between two arrays of objects and return each match int
how to find objects that match specific keys between two arrays of objects and return each match int

Time:10-16

I have two arrays of objects, one array contains objects that represent user data.

const userData = [
    {
      user_name: "Tania",
      email: "[email protected]",
      partido: "8",
      categoria_1: "1",
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Jean",
      email: "[email protected]",
      partido: "24",
      categoria_1: null,
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Vania",
      email: "[email protected]",
      partido: "13",
      categoria_1: null,
      categoria_2: "2",
      categoria_3: null
    },
    {
      user_name: "Rick",
      email: "[email protected]",
      partido: "13",
      categoria_1: "1",
      categoria_2: "2",
      categoria_3: "3"
    }
  ],

A second array contains objects that represent collections.

  collectionData = [
    {
      partido: "8",
      Equipo_Local: "Argentina",
      Equipo_Visitante: "Arabia Saudí",
      categoria_1: "1",
      categoria_2: "No dis",
      categoria_3: "No dis"
    },
    {
      partido: "24",
      Equipo_Local: "Argentina",
      Equipo_Visitante: "México",
      categoria_1: "No dis",
      categoria_2: "2",
      categoria_3: "No dis"
    },
    {
      partido: "13",
      Equipo_Local: "Polonia",
      Equipo_Visitante: "Argentina",
      categoria_1: "No dis",
      categoria_2: "2",
      categoria_3: "3"
    }
  ];

Features

  1. All objects in both arrays include the properties: "partido", "category_1", "category_2", "category_3", but can include more properties.
  2. The Listed properties change their values dynamically.

My starting point is to store each listed property in independent variables.

On the next line, pass as arguments the arrays where I want to find and match the specifics keys. Start with "partido" property searching in both arrays for the first match, if it finds the match or matches, it returns a new array of objects with the matches found for that property.

Start by looping through each objects in userData and dataCollection arrays. In this case, I search for matches using each key in both object arrays. And I get two matches partido: "8" and partido: "13", then store that matches inside the new variable named matchPartido array and return matchPartido.

  const checkPartido = ["partido"]
  const checkCategoria_1 = ["categoria_1"]
  const checkCategoria_2 = ["categoria_2"]
  const checkCategoria_3 = ["categoria_3"]

function getMatches(
  first,
  second,
  checkPartido,
  checkCategoria_1,
  checkCategoria_2,
  checkCategoria_3) {

  let finalMatches = []
  let matchPartido = []
  let matchCat_1 = []
  let matchCat_2 = []
  let matchCat_3 = []

  first.forEach((userMatch) => {
    second.forEach((collection) => {
      const isMatchPartido = checkPartido.every((key) => {
        return collection[key] === userMatch[key];
      });
      if (
        isMatchPartido &&
        !matchPartido.find((match) => match === userMatch)
      ) {
        matchPartido.push(userMatch);
      }
    });
  });

Now I go for the next match, which is category_1, categoria_2 and categoria_3 properties stored in the variables named checkCategory_1, checkCategory_2, checkCategory_3.

  matchPartido.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_1.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_1.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_1.push(userMatch)
        //console.log(matchCat_1)
        return matchCat_1
      }
    });
  });

  matchCat_1.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_2.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_2.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_2.push(userMatch)
        //console.log(matchCat_2)
        return matchCat_2
      }
    });
  });

  matchCat_2.forEach((userMatch) => {
    second.forEach((newCollection) => {
      const isMatchCategory = checkCategoria_3.every((key) => {
        return newCollection[key] === userMatch[key]
      });
      if (
        isMatchCategory &&
        !matchCat_3.find((match) => {
          return match === userMatch
        })
      ) {
        matchCat_3.push(userMatch)
        //console.log(matchCat_3)
        return matchCat_3
      }
    });
  });

  return (finalMatches = [...matchCat_1, matchCat_2, matchCat_3])
}
console.log(
  getFirstMatches(
    userData,
    collectionData,
    checkPartido,
    checkCategoria_1,
    checkCategoria_2,
    checkCategoria_3
  )
)

That's work OK... BUT.

I need to return an array of matched for partido 8

Now i have one match for `partido:"8"`, I mean only one user pick `partido: "8"` then check if categoria_1 property match, if not go categoria_2 and last categoria_3, there is one match categoria_1 property and return the array like the following.
[
{
user_name: "Tania"
email: "[email protected]"
partido: "8"
categoria_1: "1"
},{},{}...
]

Then for partido 24

Now i have one match for `partido:"24"`, I mean only one user pick `partido: "24"` then check if categoria_1 property match, if not, go categoria_2 and last categoria_3, there is one match categoria_2 property and return the array like the following.
[
{
user_name: "Jean"
email: "[email protected]"
partido: "24",
categoria_2: "2",
},{},{}...
]

And last for partido 13

Now i have two matches for `partido:"13"`, I mean two users pick `partido: "13"` then check if categoria_1 property match, if not go categoria_2 and last categoria_3, there is two matches categoria_2 and categoria_3 properties and return the array like the following.
[
{
user_name: "Vania",
email: "[email protected]",
partido: "13",
categoria_3: "3"
},
{
user_name: "Rick",
email: "[email protected]",
partido: "13",
categoria_2: "2"
},
,
{
user_name: "Rick",
email: "[email protected]",
partido: "13",
categoria_3: "3"
},
{}, {}, {}...
]

CodePudding user response:


function findMatching(
    users, collections, matchingKeys
) {
    return users.filter(user =>
        collections.some(col =>
            matchingKeys.every(key => user[key] === col[key])
        )
    )
}

function getMatches(
    users,
    collections,
    checkPartido,
    checkCategoria_1,
    checkCategoria_2,
    checkCategoria_3) {

    let matchPartido = findMatching(users, collections, checkPartido);
    let matchCat_1 = findMatching(matchPartido, collections, checkPartido);
    let matchCat_2 = findMatching(matchCat_1, collections, checkPartido);
    let matchCat_3 = findMatching(matchCat_2, collections, checkPartido);
    let finalMatches = [matchCat_1, matchCat_2, matchCat_3]
    
    return finalMatches;
}
console.log(
    getMatches(
        userData,
        collectionData,
        ["partido"],
        ["categoria_1"],
        ["categoria_2"],
        ["categoria_3"],
    )
)

CodePudding user response:

Maybe you're looking for something like a modified 'group by'? Here reducing collectionData and aggregating matching results from userData by relevant partido and cateoria_ into the result object.

const userData = [{ user_name: "Tania", email: "[email protected]", partido: "8", categoria_1: "1", categoria_2: "2", categoria_3: null }, { user_name: "Jean", email: "[email protected]", partido: "24", categoria_1: null, categoria_2: "2", categoria_3: null }, { user_name: "Vania", email: "[email protected]", partido: "13", categoria_1: null, categoria_2: "2", categoria_3: null }, { user_name: "Rick", email: "[email protected]", partido: "13", categoria_1: "1", categoria_2: "2", categoria_3: "3" }];
const collectionData = [{ partido: "8", Equipo_Local: "Argentina", Equipo_Visitante: "Arabia Saudí", categoria_1: "1", categoria_2: "No dis", categoria_3: "No dis" }, { partido: "24", Equipo_Local: "Argentina", Equipo_Visitante: "México", categoria_1: "No dis", categoria_2: "2", categoria_3: "No dis" }, { partido: "13", Equipo_Local: "Polonia", Equipo_Visitante: "Argentina", categoria_1: "No dis", categoria_2: "2", categoria_3: "3" }];

const result = Object.values(
  collectionData.reduce((res, { partido, ...rest }) => {
    res[partido] ??= { partido, ...rest, userData: {} }

    for (const cat of ['categoria_1', 'categoria_2', 'categoria_3']) {
      if (rest[cat] !== 'No dis') {
        (res[partido].userData[cat] ??= [])
          .push(...userData
            .filter(u => u.partido === partido && u[cat] === rest[cat])
            .map(u => ({ ...u }))
          )
      }
    }
    return res;
  }, {})
);

console.log(result)

  • Related