简体   繁体   中英

Compare objects in two arrays and return based on match in javascript

I am using React for this, but the concept is in javascript. So hopefully I can leave React code out for simplicity sake.

I have two arrays that I need to filter out. My goal is to map over an array and check if a property of that object matches a property in an object of the other array.

First array looks like this:

[{id: 1}, {id: 2}, {id: 3}, {id: 4}]

Second one looks like this:

[{id: 3}, {id: 4}]

So if one object has the same id property as an object in the other array, return a react element/anything.

Here is something I got to work, but it only goes through the index and compares them. This appears to loop over the 1st array properly, but I cant seem to loop over the second array by anything other than the index.

return arr1.map((e, i) => {
  return if (e.id === arr2[i].id) {
    return <div>Match</div>
  } else {
    return <div>No Match</div>
  }
})

You could use filter on the first array ,and includes on the second array:

arr1
  .filter(e => arr2.map(e2 => e2.id).includes(e.id))
  .map(e => return (<div>Match</div>));

Your problem is you are comparing index-by-index. You want to know if the element in arr1 is anywhere in arr2, right?

I would use arr2.filter to search all of arr2. So you would have something like this:

return arr1.map((e1, i) => {
  if (arr2.filter(e2 => e2.id === e1.id).length > 0) {  // If there's a match
    return <div>Match</div>
  } else {
    return <div>No Match</div>
  }
})

UPDATE: As recommended in the comments using Array.some is better here:

return arr1.map((e1, i) => {
  if (arr2.some(e2 => e2.id === e1.id)) {  // If there's a match
    return <div>Match</div>
  } else {
    return <div>No Match</div>
  }
})

You can use vanilla js for this one. When you do this loop, check out the comparisons you are making:

Iterations (omitting ID): ArrayOne vs ArrayTwo

  1. 1 compares with 3
  2. 2 compares with 4
  3. 3 compares with undefined (will error since it's asking for undefined.id)
  4. 4 compares with undefined (will error since it's asking for undefined.id)

If your elements are always going to be in order, you can loop over the first array and build out a binary search to quickly find elements in the second. This brings your time complexity to o(n * log(n)) and will be better in the long run. If you're just looking to hit MVP, you can do this:

const myFilter = (arrayOne, arrayTwo) => {
  return arrayOne.map((objectOne) => {

    // Using findIndex over includes to be able to pass callback
    // to compare the IDs
    // returns -1 if not found

    const matchIndex = arrayTwo.findIndex((objectTwo) => {
      return objectOne.id === objectTwo.id
    })


    if (matchIndex >= 0) {
      return <div> Match </div>
    } else {
      return <div> NoMatch </div>
    }

  })
}

Your time complexity will be o(n^2) in this approach, but that may be the best case depending on your circumstances. You can also use a temporary data structure, such as a Set to get o(n) time with the tradeoff of o(n) space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM