0

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>
  }
})
1
  • what doesn't seem to work? Commented Mar 6, 2017 at 22:25

3 Answers 3

2

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>
  }
})
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, first answer I saw and it worked perfectly. Thank you for explaining my faults too, helps me learn what I was doing wrong :)
Rather than filter, some is likely more efficient as it will stop at the first match and will not create a useless array.
@RobG Great suggestion! I didn't know about some. It certainly fits better here.
1

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>));

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.