4

I got a list of object, some of them as a date property completedAt, but some of them don't. I want the most recent completed object first in the list, the ones that does not have a completedAt property I want to appears last, and I do not care about their order, as long as the are after alle the dated objects.

const list = [
  {
    id: '40',
    completedAt: '2019-08-06T09:50:39.219Z'
  },
  {
    id: '45'
  },
  {
    id: '73',
    completedAt: '2018-08-06T09:51:19.362Z'
  },
  {
    id: '74',
    completedAt: '2019-08-06T09:51:00.279Z'
  },
  {
    id: '96',
    completedAt: '2019-08-06T09:51:12.761Z'
  }
];

const sortedList = list.sort((a, b) => { return new Date (b.completedAt) - new Date (a.completedAt) });

console.log(sortedList)

This function does do something to the order of the list, but they are not sorted correctly.

FYI I also have Ramda.js available if you know any ramda trick, they are more than welcome?

Rasmus Puls
  • 3,009
  • 7
  • 21
  • 58
  • Probably a duplicate of [*Sort array by ISO 8601 date*](https://stackoverflow.com/questions/12192491/sort-array-by-iso-8601-date). – RobG Aug 06 '19 at 11:43

3 Answers3

3

You could check for truthyness and sort the date by string, as you have already ISO 8601 date string.

BTW, Array#sort sorts in situ (in place).

const list = [{ id: '40', completedAt: '2019-08-06T09:50:39.219Z' }, { id: '45' }, { id: '73', completedAt: '2018-08-06T09:51:19.362Z' }, { id: '74', completedAt: '2019-08-06T09:51:00.279Z' }, { id: '96', completedAt: '2019-08-06T09:51:12.761Z' }];

list.sort((a, b) =>
    !a.completedAt - !b.completedAt ||
    b.completedAt.localeCompare(a.completedAt)
);

console.log(list);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

I do it in this way...

const list = [{
    id: '40',
    completedAt: '2019-08-06T09:50:39.219Z'
  },
  {
    id: '45'
  },
  {
    id: '73',
    completedAt: '2018-08-06T09:51:19.362Z'
  },
  {
    id: '74',
    completedAt: '2019-08-06T09:51:00.279Z'
  },
  {
    id: '96',
    completedAt: '2019-08-06T09:51:12.761Z'
  }
];

const sortedList = list.sort((a, b) => {
  if (a.completedAt == undefined) {
    return 1;
  }

  if (b.completedAt == undefined) {
    return -1;
  }
  const a1 = new Date(a.completedAt).getTime();
  const b1 = new Date(b.completedAt).getTime();
  
  return b1 - a1;
});

console.log(sortedList)
adiga
  • 34,372
  • 9
  • 61
  • 83
Ivan Karaman
  • 1,224
  • 1
  • 7
  • 11
0

This would work with a little hack-

const list = [
  {
    id: '40',
    completedAt: '2019-08-06T09:50:39.219Z'
  },
  {
    id: '45'
  },
  {
    id: '73',
    completedAt: '2018-08-06T09:51:19.362Z'
  },
  {
    id: '74',
    completedAt: '2019-08-06T09:51:00.279Z'
  },
  {
    id: '96',
    completedAt: '2019-08-06T09:51:12.761Z'
  }
];

const sortedList = list.filter((data) => data.hasOwnProperty('completedAt')).sort((function (a, b) { 
                              return new Date(a.completedAt) - new Date(b.completedAt)
                            })).concat(list.filter((data) => !data.hasOwnProperty('completedAt')));

console.log(sortedList)