1

In React, I have an array of objects with an createdAt attribute which I'm trying to sort on. However the sort doesn't seem to work properly because some it comes out in the wrong order. I've written the following code in Node.js for testing... any help would be appreciated.

const moment = require('./node_modules/moment/moment.js')

const sortObjects = () => {
  const objects = [
    {id: "cje633i3v03wl0130lsse3zev", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cjeqtudhd000u0149skzacpq5", createdAt: "2018-03-14T08:31:57.000Z"},
    {id: "cje633goc03vn01309m2iocas", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633k1z03ww0130ce27niez", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k3303x50130n1a7vnft", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k5b03xa0130m07ndgpn", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k2y03x10130q1076pq4", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k0b03wq0130bmg0t6rd", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633gmp03ve0130xu314ti4", createdAt: "2018-02-27T20:07:47.000Z"},
    {id: "cje633i2x03wd0130cqk5sdap", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i1w03w60130rfpngz0b", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i1u03w301307s44jfyy", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i3i03wh0130f3t1iyl4", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633gp803vw0130frck18wq", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633gos03vs0130tzv7xfpe", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633gnu03vj0130nnt4abin", createdAt: "2018-02-27T20:07:47.000Z"},
    {id: "cje633enx03uo0130qw0r35l6", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eot03uw0130r42aqbox", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eou03uy0130hdwg0uvn", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633epl03v30130hsugr6vp", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eps03v70130xr826vf2", createdAt: "2018-02-27T20:07:45.000Z"},
  ]
  objects.sort( (a, b) => moment.utc(b.createdAt).isAfter(moment.utc(a.createdAt)));
  console.log('objects',objects)
}

sortObjects()

Update - here's the output

[ { id: 'cje633i1w03w60130rfpngz0b', createdAt: '2018-02-27T20:07:49.000Z' },
   { id: 'cje633i3v03wl0130lsse3zev', createdAt: '2018-02-27T20:07:49.000Z' },
   { id: 'cje633i3i03wh0130f3t1iyl4', createdAt: '2018-02-27T20:07:49.000Z' },
   { id: 'cje633k1z03ww0130ce27niez', createdAt: '2018-02-27T20:07:52.000Z' },
   { id: 'cje633k3303x50130n1a7vnft', createdAt: '2018-02-27T20:07:52.000Z' },
   { id: 'cje633k5b03xa0130m07ndgpn', createdAt: '2018-02-27T20:07:52.000Z' },
   { id: 'cje633k2y03x10130q1076pq4', createdAt: '2018-02-27T20:07:52.000Z' },
   { id: 'cje633k0b03wq0130bmg0t6rd', createdAt: '2018-02-27T20:07:52.000Z' },
   { id: 'cje633i1u03w301307s44jfyy', createdAt: '2018-02-27T20:07:49.000Z' },
   { id: 'cje633i2x03wd0130cqk5sdap', createdAt: '2018-02-27T20:07:49.000Z' },
   { id: 'cjeqtudhd000u0149skzacpq5', createdAt: '2018-03-14T08:31:57.000Z' },
   { id: 'cje633goc03vn01309m2iocas', createdAt: '2018-02-27T20:07:48.000Z' },
   { id: 'cje633gp803vw0130frck18wq', createdAt: '2018-02-27T20:07:48.000Z' },
   { id: 'cje633gos03vs0130tzv7xfpe', createdAt: '2018-02-27T20:07:48.000Z' },
   { id: 'cje633gmp03ve0130xu314ti4', createdAt: '2018-02-27T20:07:47.000Z' },
   { id: 'cje633gnu03vj0130nnt4abin', createdAt: '2018-02-27T20:07:47.000Z' },
   { id: 'cje633enx03uo0130qw0r35l6', createdAt: '2018-02-27T20:07:45.000Z' },
   { id: 'cje633eot03uw0130r42aqbox', createdAt: '2018-02-27T20:07:45.000Z' },
   { id: 'cje633eou03uy0130hdwg0uvn', createdAt: '2018-02-27T20:07:45.000Z' },
   { id: 'cje633epl03v30130hsugr6vp', createdAt: '2018-02-27T20:07:45.000Z' },
   { id: 'cje633eps03v70130xr826vf2', createdAt: '2018-02-27T20:07:45.000Z' } ]
4
  • I think (not sure) you do moment(b.createdAt).utc().isAfter(etc) Commented Mar 15, 2018 at 17:35
  • In what order does the output come? Could you post the output as well? Commented Mar 15, 2018 at 17:36
  • What does isAfter return? Maybe its a boolean? Commented Mar 15, 2018 at 17:38
  • isAfter() returns a boolean -> momentjs.com/docs/#/query/is-after Commented Mar 15, 2018 at 17:40

5 Answers 5

3

You are returning true or false from the sort callback when you should return a number. Aside from that you don't need moment.js to sort by those dates. You can just use:

objects.sort( (a, b) => new Date(a.createdAt) - new Date(b.createdAt));

to sort in ascending order, or flip a and b to sort in descending order.

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

Comments

1

You could treat the ISO 8601 date strings as stings. They are sortable without using date methods, as long as they are un thge same time zone (which is actually zulu (UTC)).

const objects = [{ id: "cje633i3v03wl0130lsse3zev", createdAt: "2018-02-27T20:07:49.000Z" }, { id: "cjeqtudhd000u0149skzacpq5", createdAt: "2018-03-14T08:31:57.000Z" }, { id: "cje633goc03vn01309m2iocas", createdAt: "2018-02-27T20:07:48.000Z" }, { id: "cje633k1z03ww0130ce27niez", createdAt: "2018-02-27T20:07:52.000Z" }, { id: "cje633k3303x50130n1a7vnft", createdAt: "2018-02-27T20:07:52.000Z" }, { id: "cje633k5b03xa0130m07ndgpn", createdAt: "2018-02-27T20:07:52.000Z" }, { id: "cje633k2y03x10130q1076pq4", createdAt: "2018-02-27T20:07:52.000Z" }, { id: "cje633k0b03wq0130bmg0t6rd", createdAt: "2018-02-27T20:07:52.000Z" }, { id: "cje633gmp03ve0130xu314ti4", createdAt: "2018-02-27T20:07:47.000Z" }, { id: "cje633i2x03wd0130cqk5sdap", createdAt: "2018-02-27T20:07:49.000Z" }, { id: "cje633i1w03w60130rfpngz0b", createdAt: "2018-02-27T20:07:49.000Z" }, { id: "cje633i1u03w301307s44jfyy", createdAt: "2018-02-27T20:07:49.000Z" }, { id: "cje633i3i03wh0130f3t1iyl4", createdAt: "2018-02-27T20:07:49.000Z" }, { id: "cje633gp803vw0130frck18wq", createdAt: "2018-02-27T20:07:48.000Z" }, { id: "cje633gos03vs0130tzv7xfpe", createdAt: "2018-02-27T20:07:48.000Z" }, { id: "cje633gnu03vj0130nnt4abin", createdAt: "2018-02-27T20:07:47.000Z" }, { id: "cje633enx03uo0130qw0r35l6", createdAt: "2018-02-27T20:07:45.000Z" }, { id: "cje633eot03uw0130r42aqbox", createdAt: "2018-02-27T20:07:45.000Z" }, { id: "cje633eou03uy0130hdwg0uvn", createdAt: "2018-02-27T20:07:45.000Z" }, { id: "cje633epl03v30130hsugr6vp", createdAt: "2018-02-27T20:07:45.000Z" }, { id: "cje633eps03v70130xr826vf2", createdAt: "2018-02-27T20:07:45.000Z" }];

objects.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
  
console.log(objects);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

*Assuming they are all using the same timezone, which they indeed do appear to be from the OP's question.
0
var sortedObj = objects.sort(function(a,b){
    return new Date(b.createdAt) - new Date(a.createdAt);
});

console.log(sortedObj)

Comments

0

Compare them as strings. a.createdAt < b.createdAt? 1 : -1 will sort descending. a.createdAt > b.createdAt? 1 : -1 sill sort ascendant

const sortObjects = () => {
  const objects = [
    {id: "cje633i3v03wl0130lsse3zev", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cjeqtudhd000u0149skzacpq5", createdAt: "2018-03-14T08:31:57.000Z"},
    {id: "cje633goc03vn01309m2iocas", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633k1z03ww0130ce27niez", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k3303x50130n1a7vnft", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k5b03xa0130m07ndgpn", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k2y03x10130q1076pq4", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633k0b03wq0130bmg0t6rd", createdAt: "2018-02-27T20:07:52.000Z"},
    {id: "cje633gmp03ve0130xu314ti4", createdAt: "2018-02-27T20:07:47.000Z"},
    {id: "cje633i2x03wd0130cqk5sdap", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i1w03w60130rfpngz0b", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i1u03w301307s44jfyy", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633i3i03wh0130f3t1iyl4", createdAt: "2018-02-27T20:07:49.000Z"},
    {id: "cje633gp803vw0130frck18wq", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633gos03vs0130tzv7xfpe", createdAt: "2018-02-27T20:07:48.000Z"},
    {id: "cje633gnu03vj0130nnt4abin", createdAt: "2018-02-27T20:07:47.000Z"},
    {id: "cje633enx03uo0130qw0r35l6", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eot03uw0130r42aqbox", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eou03uy0130hdwg0uvn", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633epl03v30130hsugr6vp", createdAt: "2018-02-27T20:07:45.000Z"},
    {id: "cje633eps03v70130xr826vf2", createdAt: "2018-02-27T20:07:45.000Z"},
  ]
  objects.sort( (a, b) =>a.createdAt < b.createdAt? 1 : -1);
  console.log('objects',objects)
}

sortObjects()

Comments

0

I can confirm to you that, due the unstable sort algorithm used by Javascript you have to return 3 possible values: 1,0 and -1. The sort order for elements with the same value is not guarantee. So a correct sort function call could be (in pure JavaScript)

var a = [{key:2},{key:1},{key:2},{key:3}]
//sort in ascending order
a = a.sort((a,b)=>{ 
    return (a<b) ? -1 : ((a>b) ? 1 : 0)
});

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.