72

Given the following array of objects, I need to ascending sort them by the date field.

var myArray = [
  {
    name: "Joe Blow",
    date: "Mon Oct 31 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "Sam Snead",
    date: "Sun Oct 30 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "John Smith",
    date: "Sat Oct 29 2016 00:00:00 GMT-0700 (PDT)"  
  }
];

In the above example, the final result would be John Smith, Sam Snead, and Joe Blow.

I am trying to use lodash's _.sortBy(), but I can't get any sorting to take place no matter how I try to use it:

_.sortBy(myArray, function(dateObj) {
  return dateObj.date;
});

or

_.sortBy(myArray, 'date');

What do I need to change to get my array sorted properly? I also have Moment.js, so I can use it to format the date string if needed. I tried converting the date property using .unix(), but that didn't make a difference.

Thanks.

6
  • Are those date objects, or date strings? Commented Dec 5, 2016 at 1:15
  • Standard Javascript date strings. As I said, I can convert them to another format with Moment first if needed, but converting to unix didn't seem to work, and that seems to be the easiest format for sorting. Commented Dec 5, 2016 at 1:17
  • Are the values dates or strings? Commented Dec 5, 2016 at 1:20
  • _.sortBy doesn't seem to sort in place (unlike Array#sort method) Commented Dec 5, 2016 at 1:20
  • 3
    _.sortBy(myArray, ['date']) should work. For '2018-08-28T17:38:00' date format it works. Commented Aug 17, 2018 at 14:42

8 Answers 8

113

You don't really need lodash. You can use JavaScript's Array.prototype.sort method.

You'll need to create Date objects from your date strings before you can compare them.

var myArray = [{
  name: "Joe Blow",
  date: "Mon Oct 31 2016 00:00:00 GMT-0700 (PDT)"
}, {
  name: "Sam Snead",
  date: "Sun Oct 30 2016 00:00:00 GMT-0700 (PDT)"
}, {
  name: "John Smith",
  date: "Sat Oct 29 2016 00:00:00 GMT-0700 (PDT)"
}];

myArray.sort(function compare(a, b) {
  var dateA = new Date(a.date);
  var dateB = new Date(b.date);
  return dateA - dateB;
});

console.log(myArray);

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

4 Comments

And it has great Browser support. It's been in the spec since ECMAScript 3, which means it works in all browsers. (even IE7)
Since the OP has moment.js, it should be used to parse the dates, not the built–in Date.
JavaScript sort is not stable sort, lodash sortBy and orderBy are stable. I have encountered a problem about this, and lodash solved it. This method performs a stable sort, that is, it preserves the original sort order of equal elements. lodash.com/docs/4.17.10#sortBy
Also to add safari does its sorting differently. Found it the hard way, if you already have lodash or other libraries , best to use them.
27

Here's a solution using standard Javascript by converting both values to date object and comparing their value.

myArray.sort((d1, d2) => new Date(d1.date).getTime() - new Date(d2.date).getTime());

A complete snippet:

var myArray = [
  {
    name: "Joe Blow",
    date: "Mon Oct 31 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "Sam Snead",
    date: "Sun Oct 30 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "John Smith",
    date: "Sat Oct 29 2016 00:00:00 GMT-0700 (PDT)"  
  }
];

myArray.sort((d1, d2) => new Date(d1.date).getTime() - new Date(d2.date).getTime());

console.log(myArray);

Comments

24

Your date values are strings, so you need to use the new Date() constructor to change them to javascript date objects. This way you can sort them (using _.sortBy).

var myArray = [
  {
    name: "Joe Blow",
    date: "Mon Oct 31 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "Sam Snead",
    date: "Sun Oct 30 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "John Smith",
    date: "Sat Oct 29 2016 00:00:00 GMT-0700 (PDT)"  
  }
];

myArray = _.sortBy(myArray, function(dateObj) {
  return new Date(dateObj.date);
});

console.log(myArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>

Comments

17

If you are trying to use lodash to sort dates in ascending or descending order for your array of objects, you should use _.orderBy instead of _.sortBy

https://lodash.com/docs/4.17.15#orderBy, this method allows specifying sort orders either by 'asc' or 'desc'

An example would be:

const sortedArray = _(myArray.orderBy([
      function(object) {
        return new Date(object.date);
      }],["desc"])

Comments

10

A cleaner way using Lodash orderBy:

import _ from 'lodash'

const sortedArray = _.orderBy(myArray, [(obj) => new Date(obj.date)], ['asc'])

2 Comments

where you pass array here?
@ßãlãjî - First param is the array, i.e. _.orderBy(YOUR_ARRAY, ['asc']). Also, asc can be desc also for descending sorting instead of ascending...see more here
7

just write _.sortBy({yourCollection}, {the field name});

lodash will automatically figure that this is a date and it'll work like a magic!

Awesome!

3 Comments

Will lodash really detect this automatically? Even if the provided date is a ISO string?
@Marek, yes lodash detects automatically that if string is ISO Date String, so it then sorts it as Date :)
Yes, if the date is in ISO_8601 format. From Wikipedia as a general principle of the standard: "Date and time values are ordered from the largest to smallest unit of time: year, month (or week), day, hour, minute, second, and fraction of second. The lexicographical order of the representation thus corresponds to chronological order, except for date representations involving negative years or time offset. This allows dates to be naturally sorted by, for example, file systems.
3

Inspired by others answers and noticing that you used moment.js and lodash, you can combine both with _.orderBy lodash method:

import moment from 'moment'
import * as _ from 'lodash'

let myArray = [
  {
    name: "Joe Blow",
    date: "Mon Oct 31 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "Sam Snead",
    date: "Sun Oct 30 2016 00:00:00 GMT-0700 (PDT)"
  },
  {
    name: "John Smith",
    date: "Sat Oct 29 2016 00:00:00 GMT-0700 (PDT)"  
  }
];


myArray = _.orderBy(myArray, [(item) => {
            return moment(item.date).format('YYYY-MM-DD')
         }], ['desc'])

Comments

2

this has worked for me

myArray = _.orderBy(myArray, [item => item.lastModified], ['desc']);

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.