Karl Bateman Karl Bateman - 6 months ago 30
Javascript Question

Lodash create a collection from a collection

I have the following data structure;

var data = [{
"username": "admin",
"update": "19/07/2015 17:44:14"
}, {
"username": "admin",
"update": "19/07/2015 17:00"
}, {
"username": "joebloggs",
"update": "19/07/2015 17:00"
}, {
"username": "joebloggs",
"update": "19/07/2015 17:44:14"
}];


Using the lodash library, I would like to create the following data structure;

var newData = [{
"username": "admin",
"update": "19/07/2015 17:00"
}, {
"username": "joebloggs",
"update": "19/07/2015 17:00"
}];


As you can see, I need to remove the duplicate names and store only the most recent date. Any help with this would be greatly appreciated,

Answer

You can make use of orderBy() to order the collection by the update date value in descending order and then use uniqBy() to remove duplicate values.

var data = [{
    "username": "admin",
    "update": "19/07/2015 17:44:14"
}, {
    "username": "admin",
    "update": "19/07/2015 17:00"
}, {
    "username": "joebloggs",
    "update": "19/07/2015 17:00"
}, {
    "username": "joebloggs",
    "update": "19/07/2015 17:44:14"
}];

var result = _(data)
  .orderBy(v => new Date(v.update), 'desc')
  .uniqBy('username')
  .value();

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.12.0/lodash.min.js"></script>

UPDATE

I noticed that the update date values are not compliant with IETF-compliant RFC 2822 timestamps and version of ISO8601 date formats, check Date documentation as a reference. Therefore the solution above does not apply properly with the most recent date criteria.

You have two options to solve this problem:

  1. Change the way you format the update date values from the source (backend or whichever resource you got it from). This way the solution above still applies.

  2. Convert the date format on run time. The solution for this is shown below:

var data = [{
    "username": "admin",
    "update": "19/07/2015 17:44:14"
}, {
    "username": "admin",
    "update": "19/07/2015 17:00"
}, {
    "username": "joebloggs",
    "update": "19/07/2015 17:00"
}, {
    "username": "joebloggs",
    "update": "19/07/2015 17:44:14"
}];

var result = _(data)
  .orderBy(v => {
    var ds = v.update.split(' ');
    ds[0] = ds[0].split('/').reverse().join('/');
    return new Date(ds.join(' '));
  }, 'desc')
  .uniqBy('username')
  .value();

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.12.0/lodash.min.js"></script>

Comments