Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Owa Aquino
19,277 PointsRemove an item in an array if the item has a duplicate.
Hello,
I'm trying to remove an item from an array if it has a duplicate. Somehow I manage to remove the duplicate item in it but I needed to remove as well that specific item with the duplicate.
example:
let array= [ 'John', 'Bean', 'John', 'Mike', 'Rose', 'John']
the expected result i wanted to see is
// ['Bean', 'Mike', 'Rose' ]
Removing "John" in the array...
Somehow this is my code
let array= [ 'John', 'Bean', 'John', 'Mike', 'Rose', 'John']
const newArray = array.reduce((unique, item) => {
return unique.includes(item) ? unique : [...unique, item];
}, []);
//result is: 'John', 'Bean', 'Mike', 'Rose' ]
Appreciate your help. Thanks!
2 Answers
Brendan Whiting
Front End Web Development Techdegree Graduate 84,738 PointsI ran your code and looked at the contents of the unique array each time it got called:
[]
[ 'John' ]
[ 'John', 'Bean' ]
[ 'John', 'Bean' ]
[ 'John', 'Bean', 'Mike' ]
[ 'John', 'Bean', 'Mike', 'Rose' ]
[ 'John', 'Bean', 'Mike', 'Rose' ]
So it starts off empty, then it adds John, and Bean. It sees the 2nd John, ignores it, adds Mike, adds Rose, sees the last John, ignores it. You might build in some way of deleting the 1st John when it sees the 2nd John, but it somehow needs to remember that when it sees the last John to not add that one either.
My solution would be to make a helper function that first reduces the list into an object that has how many of each name there are. Then you can iterate over the names in the object, and make a new list were those names have only one occurrence:
let array = [ 'John', 'Bean', 'John', 'Mike', 'Rose', 'John'];
const countNames = (list) => {
return list.reduce((acc, curr) => {
if (acc[curr]) {
acc[curr] += 1;
} else {
acc[curr] = 1;
}
return acc;
}, {})
};
const removeDuplicates = (array) => {
const nameCounts = countNames(array); // { John: 3, Bean: 1, Mike: 1, Rose: 1 }
return Object.keys(nameCounts)
.filter(name => nameCounts[name] === 1);
};
console.log(removeDuplicates(array)); // [ 'Bean', 'Mike', 'Rose' ]
This might seem like a more complex solution, but we basically end up iterating through the list once to count everything, and then iterating through the names a second time to filter out any with a count more than one. It reduces down to Big O(n) if you're into algorithm complexity.
Steven Parker
243,215 PointsYour test using "includes" will identify a duplicate only because the first instance is already in the "unique" array.
You might try doing this in two passes: first to create a list of identified duplicates, and then to create the list of only the items not previously identified as having duplicates.
Is this part of a course challenge? It might be helpful to post a link to the challenge itself.
Owa Aquino
19,277 PointsHi Steven,
Thank you very much for your advice. Nope it's not part of a course challenge. Just having a problem with a project I'm currently working on.
Cheers!
Steven Parker
243,215 PointsOK, so it occurred to me that you just need to test for uniqueness before the item is added to the "unique" array. You can do this by comparing the first and last indexes of the item. If it is unique, they will match; but if it is not unique they will be different:
const newArray = array.reduce((unique, item) => {
return array.indexOf(item) != array.lastIndexOf(item) ? unique : [...unique, item];
}, []);
And it's even simpler using "filter" instead of "reduce":
const newArray = array.filter(item => array.indexOf(item) == array.lastIndexOf(item));
Owa Aquino
19,277 PointsThanks Steven! This is great! I got lot of options.. :) I'm not really familiar with indexOf() method I have to study it first! Thank you very much!
Owa Aquino
19,277 PointsOwa Aquino
19,277 PointsHi Brendan,
Thank you for your help! I'm just going to figure out first your solution because it's new for me.
Cheers!
Owa Aquino
19,277 PointsOwa Aquino
19,277 PointsI get it now. I have to count first those names that are the same then remove the name that has more than 1 instance.
This is great! Thank you very much!