Lodash uniqBy created date?

Hi i have a data set like this

  1. ID: 1, createDate: 7-Jul
  2. ID: 1, createDate: 5-Jul
  3. ID: 2, createDate: 7-Jul
  4. ID: 2, createDate: 5-Jul

I want to take uniq values (by ID) but pick the latest version (by date). In the above examples, item 1 and 3 should be returned.

Any recommendations on cleanest way to do this?

Thanks!

Answer

You can use Array.reduce to create a map of your input objects, keyed on ID.

We’ll need to create a function to parse the createDate values since we cannot compare as strings.

If the map entry at ID is empty, or has an earlier createDate we’ll replace it on each iteration:

const input = [
    { ID: 1, createDate: '7-Jul' },
    { ID: 1, createDate: '5-Jul' },
    { ID: 2, createDate: '7-Jul' },
    { ID: 2, createDate: '5-Jul' },
    { ID: 3, createDate: '1-Jan' },
    { ID: 3, createDate: '31-Dec' }
]

// Assuming date is like 5-Jul
function parseDate(dateString) {
    const [day,month] = dateString.toLowerCase().split('-');
    const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
    const monthIndex = months.findIndex(mth => mth === month);
    return new Date(new Date().getFullYear(), monthIndex, day);
}

const result = Object.values(input.reduce((acc, cur) => { 
    // Replace the entry at ID _if_ empty or the new item is later
    if (!acc[cur.ID] || (parseDate(cur.createDate) > parseDate(acc[cur.ID].createDate))) {
       acc[cur.ID] = cur;  
    }
    return acc;
}, {}))

console.log("Result:", result)