0

How can I filter an array down to all objects that might look similar by certain keys without knowing the value of those keys?

Imagine I have an object like this:

let list = [
  { name: 'Adam',    age: '10', uniqueStuff: 'a'},
  { name: 'Brian',   age: '2',  uniqueStuff: 'b'},
  { name: 'Carley',  age: '15', uniqueStuff: 'c'},
  { name: 'Adam',    age: '2',  uniqueStuff: 'd'},
  { name: 'Christy', age: '15', uniqueStuff: 'e'},
  { name: 'Adam',    age: '10', uniqueStuff: 'f'},
]

I want the result to be:

let list = [
  { name: 'Adam',    age: '10', uniqueStuff: 'a'},
  { name: 'Adam',    age: '10', uniqueStuff: 'f'},
]

These may look like duplicates because they share the same name and age, but uniqueStuff is different. So I'm not trying to remove possible duplicates, but to get an array of all similar objects in the array.

Kind of like answering the question "how many kids do we have with the same names and same ages?"

This would be similar to MySQL's "having count(*) > 1" queries.

I'm having a really hard time searching for an answer or figuring out a LoDash method. Everything I find is about removing duplicates or getting only the duplicates so there's only 1 of each item. Instead, I want to get all the items that are duplicates and have duplicates. So each "match" in my array should have 2 or more items. For example, 2 or more 10-year old Adams, 2 or more 6-year-old Amys, and such.

Thanks in advance!

6
  • Each match has two or more entries, but do you want different matches in the same array or in separate arrays? What output do you want to see if Carley is changed to Christy? Commented Mar 16, 2022 at 19:57
  • 1
    Does this approach meet your needs? If so I can write up an answer; if not, what am I missing? Commented Mar 16, 2022 at 20:10
  • @jcalz, I would want the array to contain all people with matches. So I had two Christys in my example data, I would expect to see them with the two Adams. Commented Mar 17, 2022 at 4:16
  • I may have figured out a way to do this with Lodash's groupBy method, but my implementation is very messy. I'll look at cleaning it up and sharing that solution. Commented Mar 17, 2022 at 4:17
  • Did you look at this approach here? I'm happy to write that up as an answer, if you agree that it meets your needs. If not, then an elaboration of what you want in the question would be useful (where you edit the info into the question). Commented Mar 17, 2022 at 13:07

1 Answer 1

0
const reduced = list.reduce((prev, curr) => {
    const key = `${curr.name}, ${curr.age}`
    return {
        ...prev,
        [key]: [...(prev[key] || []), curr]
    }
}, {})

const filtered = Object.values(reduced).filter(v => v.length > 1)

const flatted = filtered.flat()

You can remove the last line if you prefer having each set of 2 in an array.

Sign up to request clarification or add additional context in comments.

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.