2

In our angularjs app we're receiving an array of dates that then need to be filtered out to only return an array full of unique dates (not strings). I tried some of the answers on SO but I think because I'm comparing dates and not strings - I'm yielding different results. Any help on what the best approach is would be very helpful. enter image description here

2 Answers 2

3

You are right, date equality is different from string equality. Dates are objects, and the === comparator for objects compares them by reference, not value. Since {} === {} in JS is false, two Dates will never be equal to each other. So, let's just turn the dates into numbers:

let dates = [new Date(), new Date('1/1/11'), new Date('1/1/11'), new Date('1/4/66')]


let uniqueDates = dates
                   .map(s => s.getTime())
                   .filter((s, i, a) => a.indexOf(s) == i)
                   .map(s => new Date(s));
                   
console.log(uniqueDates);

The logic with indexOf is that every unique value should be present only at its own position; any others are duplicates (s is current item, i is current index, and a is the array itself). Then we map the array back into Dates and return it.

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

2 Comments

thank you - the refactor of your code was the cherry on top. I think I was overcomplicating before by dismissing the idea of converting to a string and then back to date
No problem! Come to think of it, it's more straightforward to replace .toString() with .getTime(). That returns the date as a simple number, epoch time. Cleaner and a little more efficient than comparing strings.
3

If you're using lodash:

const date1 = new Date();
const date2 = new Date();
const arr = [date1, date1, date2, date2];
const uniqueDates = _.uniqBy(arr, date => date.getTime());

Uses uniqBy to ensure that we compare dates by their value and not just by object identity. See here: Compare two dates with JavaScript

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.