2

The problem is a simple one. I have an array of array of objects. Example:

[[{'name':'cat"}, {'name':'lion'}], [{'name':'elephant"},
{'name':'lion'}, {'name':'dog'}], [{'name':'tiger"}, {'name':'mouse'},
{'name':'dog'}]]

I want to remove duplicates using JS and retain only their first occurrences and remove their duplicates resulting in:

[[{'name':'cat"}, {'name':'lion'}], [{'name':'elephant"},
{'name':'dog'}], [{'name':'tiger"}, {'name':'mouse'}]]

How do I do this using loadash/ underscore? I have tried a bunch of options, first one involved passing an iteratee to the .uniq function, but it didn't work the way I wanted since these are 2d array. The other brute force method included iterating through all the arrays one by one and then doing a search to see if any of the other arrays contain the element and removing the element. Repeat this procedure until the last-1 of the sub-arrays.

Is don't like the brute force method, so wondering if there are any other methods I can retain unique elements.

Note that this is a 2D array of objects and all the posts on stack overflow answer 1D array of objects. I'm not looking to find duplicates in an array. I'm trying to find duplicates across all arrays in an array.

0

3 Answers 3

3

I nice way to deal with this is with a Set, just add your labels to the set as you filter() inside a map():

let arr = [
    [{'name':'cat'}, {'name':'lion'}], 
    [{'name':'elephant'},{'name':'lion'}, {'name':'dog'}],
    [{'name':'tiger'}, {'name':'mouse'}, {'name':'dog'}]
    ]

let known = new Set()
let filtered = arr.map(subarray => 
    subarray.filter(item => !known.has(item.name) && known.add(item.name))
)
console.log(filtered)

EDIT: If you can't use a Set, you can get the same function from a regular object:

let arr = [
    [{'name':'cat'}, {'name':'lion'}], 
    [{'name':'elephant'},{'name':'lion'}, {'name':'dog'}],
    [{'name':'tiger'}, {'name':'mouse'}, {'name':'dog'}]
    ]

let known = {}
let filtered = arr.map(subarray => 
    subarray.filter(item => !known.hasOwnProperty(item.name) && (known[item.name] = true))
)
console.log(filtered)

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

2 Comments

Cannot use a set because the platform I work with doesn't come with ES6, I'm limited to using ES5. How do we do this in ES5?
An object works about the same @abhididdigi, see edit.
2
let intervals = [
    [1, 20],
    [1, 20],
    [1, 20]
]
intervals = [...new Set(intervals.map(e => JSON.stringify(e)))].map(e => JSON.parse(e)) // [[1,20]]

1 Comment

consider adding more explanation to the answer to help us understand more instead of just posting a block of code
0
var a = [];
a.push( [1,2,3], [4,5,6], [1,2,3], [4,5,6] );
a.forEach( ( chunk, idx ) => { a[idx] = JSON.stringify(chunk); } );
a = [ ...new Set(a) ];
a.forEach( ( chunk, idx ) => { a[idx] = JSON.parse(chunk); } );

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.