1

Sorry I am new to javascript, but I am currently attempting to sort my JSON object according to attribute but right now it does not sort.

For example: I try to do this:

function sortByKey(array, key)
{

  return array.sort(function(a, b) {
  let x = a[key];
  let y = b[key];
  x = new Date(a.dateModified);
  y = new Date(b.dateModified);
  return x>y ? -1 : x<y ? 1 : 0;
});
}

And I try to sort according to "lastCompletedEvaldate" :

[
  {
    "_id": "<a MongoDB object ID>",
    "name": "Fred Flintstone",
    "email": "fflintstone@hotmail.com",
    "sex": "male",
    "tags": [
      "foo",
      "bar"
    ],
    "lastCompletedEvalDate": "2018-05-14 12:02:14.955",
    "pendingEvalSentDate": null,
    "pendingEvalViewedEmailDate": null,
    "pendingEvalClickedLinkDate": null

  },
  {
    "_id": "<a MongoDB object ID>",
    "name": "Barney Rubble",
    "email": "barney@gmail.com",
    "sex": "intersex",
    "tags": [],
    "lastCompletedEvalDate": "2018-05-14 12:02:14.954",
    "pendingEvalSentDate": "2018-05-14 12:02:14.955",
    "pendingEvalViewedEmailDate": "2018-05-14 12:02:14.955",
    "pendingEvalClickedLinkDate": "2018-05-14 12:02:14.955"

  },
  {
    "_id": "<a MongoDB object ID>",
    "name": "Bambam Rubble",
    "email": "bam@bam.com",
    "sex": null,
    "tags": [
      "baz"
    ],
    "lastCompletedEvalDate": "2018-05-14 12:02:14.955",
    "pendingEvalSentDate": null,
    "pendingEvalViewedEmailDate": null,
    "pendingEvalClickedLinkDate": null
  }
]

However, when I use the function like so:

let temp = sortByKey(file, 'lastCompletedEvalDate');

and output it using a get request:

router.get('/dash/participant', function(req, res){
  res.send(temp);
});

I still get the same output back not sorted. Am I doing something wrong.

Michael Gee
  • 501
  • 2
  • 9
  • 21
  • Yes. You set x to `a[key]`. key holds `"lastCompletedEvalDate"`. `a.lastCompletedEvalDate` exists and looks like a date. But then. you completely ignore that value and set `x` to a `Date` created from `a.dateModified` ... which does not exist. – Tibrogargan Jul 12 '18 at 23:23

3 Answers3

2

You should always avoid the built-in Date parser if there is any viable alternative (see Why does Date.parse give incorrect results?). In this case, the string "2018-05-14 12:02:14.955" is not consistent with the format in ECMA-262 so an implementation may return an invalid date (and Safari does).

Since the date strings will sort as strings, use localeCompare instead of creating Date objects:

function sortByKey(array, key) {
  return array.sort((a,b) => a[key].localeCompare(b[key]));
}

var data = [{
    "lastCompletedEvalDate": "2018-05-14 12:02:14.955",
    "pendingEvalSentDate": null,
  },
  {
    "lastCompletedEvalDate": "2018-05-14 12:02:14.954",
    "pendingEvalSentDate": "2018-05-14 12:02:14.955",
  },
  {
    "lastCompletedEvalDate": "2018-05-14 12:02:14.955",
    "pendingEvalSentDate": null,
  }
];

sortByKey(data, 'lastCompletedEvalDate');

console.log(data)
RobG
  • 142,382
  • 31
  • 172
  • 209
1

In your code you sort the array by dateModified ignoring key. Try following

function sortByKey(array, key)
{
  return array.sort((a, b) => 
    -(a[key] > b[key]) || +(a[key] < b[key])
  );
}

I replaced new Date with simple string comparison, see comments below.

Also, Array.prototype.sort does sort in place, so to keep the original array you probably want to clone it first:

let temp = [...file];
sortByKey(temp, 'lastCompletedEvalDate');
dhilt
  • 18,707
  • 8
  • 70
  • 85
  • or for a simpler version: `return x.getTime() - y.getTime()` – Tibrogargan Jul 12 '18 at 23:25
  • @Tibrogargan yeah, but the shortest version, I believe, is `array.sort((a, b) => -(a[key] > b[key]) || +(a[key] < b[key]))` – dhilt Jul 12 '18 at 23:41
  • `new Date("2018-05-14 12:02:14.955")` returns an invalid date in Safari (because the string is not consistent with the format defined in ECMA-262). There is no need to use Date objects at all, the dates can be sorted as strings. – RobG Jul 12 '18 at 23:58
0

You can try something like this:

function sortByKey(array, key)
{ 
   return array.sort((a, b) => 
      new Date(a[key]) - new Date(b[key])
   ) 
}

You can also check in the documentation