Sorting dates in this format (DD-MM-YYYY)
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
6
down vote
favorite
Is this the correct and an elegant way to sort the dates in the format (DD-MM-YYYY) in ascending order?
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-'), date2 = date2.split('-');
let day1 = parseInt(date1[0]);
let day2 = parseInt(date2[0]);
let month1 = parseInt(date1[1]);
let month2 = parseInt(date2[1]);
let year1 = parseInt(date1[2]);
let year2 = parseInt(date2[2]);
if (year1 !== year2)
return year1 - year2;
else if (month1 !== month2)
return month1 - month2;
else
return day1 - day2;
);
There is also this way, as Cris Luengo said in the comments, I can directly compare the strings.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('-');
date2 = date2.split('-').reverse().join('-');
if (date1 < date2)
return -1;
else if (date1 > date2)
return 1;
else
return 0;
);
Which way is more performant? How do I measure that?
javascript performance sorting datetime comparative-review
 |Â
show 8 more comments
up vote
6
down vote
favorite
Is this the correct and an elegant way to sort the dates in the format (DD-MM-YYYY) in ascending order?
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-'), date2 = date2.split('-');
let day1 = parseInt(date1[0]);
let day2 = parseInt(date2[0]);
let month1 = parseInt(date1[1]);
let month2 = parseInt(date2[1]);
let year1 = parseInt(date1[2]);
let year2 = parseInt(date2[2]);
if (year1 !== year2)
return year1 - year2;
else if (month1 !== month2)
return month1 - month2;
else
return day1 - day2;
);
There is also this way, as Cris Luengo said in the comments, I can directly compare the strings.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('-');
date2 = date2.split('-').reverse().join('-');
if (date1 < date2)
return -1;
else if (date1 > date2)
return 1;
else
return 0;
);
Which way is more performant? How do I measure that?
javascript performance sorting datetime comparative-review
3
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare stringsdate1[2]
todate2[2]
, if those are equal, compare[1]
, etc.
â Cris Luengo
Jan 4 at 4:37
Right, but in my case, the days come first. So this comparison'31-12-2017' < '02-01-2018';
will return false.
â Mark Adel
Jan 4 at 4:47
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
11
Don't store dates as strings within your application. At the earliest possible time, convert them to properDate
objects, and if a string representation is necessary, convert them to aString
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just bedates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
1
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.
â Igor Soloydenko
Jan 4 at 18:26
 |Â
show 8 more comments
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Is this the correct and an elegant way to sort the dates in the format (DD-MM-YYYY) in ascending order?
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-'), date2 = date2.split('-');
let day1 = parseInt(date1[0]);
let day2 = parseInt(date2[0]);
let month1 = parseInt(date1[1]);
let month2 = parseInt(date2[1]);
let year1 = parseInt(date1[2]);
let year2 = parseInt(date2[2]);
if (year1 !== year2)
return year1 - year2;
else if (month1 !== month2)
return month1 - month2;
else
return day1 - day2;
);
There is also this way, as Cris Luengo said in the comments, I can directly compare the strings.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('-');
date2 = date2.split('-').reverse().join('-');
if (date1 < date2)
return -1;
else if (date1 > date2)
return 1;
else
return 0;
);
Which way is more performant? How do I measure that?
javascript performance sorting datetime comparative-review
Is this the correct and an elegant way to sort the dates in the format (DD-MM-YYYY) in ascending order?
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-'), date2 = date2.split('-');
let day1 = parseInt(date1[0]);
let day2 = parseInt(date2[0]);
let month1 = parseInt(date1[1]);
let month2 = parseInt(date2[1]);
let year1 = parseInt(date1[2]);
let year2 = parseInt(date2[2]);
if (year1 !== year2)
return year1 - year2;
else if (month1 !== month2)
return month1 - month2;
else
return day1 - day2;
);
There is also this way, as Cris Luengo said in the comments, I can directly compare the strings.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('-');
date2 = date2.split('-').reverse().join('-');
if (date1 < date2)
return -1;
else if (date1 > date2)
return 1;
else
return 0;
);
Which way is more performant? How do I measure that?
javascript performance sorting datetime comparative-review
edited Jan 4 at 14:56
200_success
124k14143401
124k14143401
asked Jan 4 at 4:25
Mark Adel
102110
102110
3
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare stringsdate1[2]
todate2[2]
, if those are equal, compare[1]
, etc.
â Cris Luengo
Jan 4 at 4:37
Right, but in my case, the days come first. So this comparison'31-12-2017' < '02-01-2018';
will return false.
â Mark Adel
Jan 4 at 4:47
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
11
Don't store dates as strings within your application. At the earliest possible time, convert them to properDate
objects, and if a string representation is necessary, convert them to aString
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just bedates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
1
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.
â Igor Soloydenko
Jan 4 at 18:26
 |Â
show 8 more comments
3
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare stringsdate1[2]
todate2[2]
, if those are equal, compare[1]
, etc.
â Cris Luengo
Jan 4 at 4:37
Right, but in my case, the days come first. So this comparison'31-12-2017' < '02-01-2018';
will return false.
â Mark Adel
Jan 4 at 4:47
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
11
Don't store dates as strings within your application. At the earliest possible time, convert them to properDate
objects, and if a string representation is necessary, convert them to aString
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just bedates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
1
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.
â Igor Soloydenko
Jan 4 at 18:26
3
3
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare strings
date1[2]
to date2[2]
, if those are equal, compare [1]
, etc.â Cris Luengo
Jan 4 at 4:37
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare strings
date1[2]
to date2[2]
, if those are equal, compare [1]
, etc.â Cris Luengo
Jan 4 at 4:37
Right, but in my case, the days come first. So this comparison
'31-12-2017' < '02-01-2018';
will return false.â Mark Adel
Jan 4 at 4:47
Right, but in my case, the days come first. So this comparison
'31-12-2017' < '02-01-2018';
will return false.â Mark Adel
Jan 4 at 4:47
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
11
11
Don't store dates as strings within your application. At the earliest possible time, convert them to proper
Date
objects, and if a string representation is necessary, convert them to a String
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just be dates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
Don't store dates as strings within your application. At the earliest possible time, convert them to proper
Date
objects, and if a string representation is necessary, convert them to a String
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just be dates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
1
1
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --
YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.â Igor Soloydenko
Jan 4 at 18:26
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --
YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.â Igor Soloydenko
Jan 4 at 18:26
 |Â
show 8 more comments
4 Answers
4
active
oldest
votes
up vote
8
down vote
accepted
UPDATE: You can run performance tests I prepared based on various code samples from the answers to this question: https://jsperf.com/cr-se-date-array-sorting/1. When I ran them, I see that my code is second best performing. The best is the one by @Kevin Cline (up voted!).
Here's my take on it. The following code uses the same idea about the string representation of date that is directly comparable for sorting.
It is not possible to tell in advance how performant will this solution be compared to one you presented above. It all depends a lot on how many dates are being sorted. If you deal with tons of dates, there will be many more invocations to the arrow function we're passing to sort(...)
. Therefore, it's not good to keep translating the date via split()
every time our arrow function is being used.
Instead, I recommend three steps:
- Translate dates into a sortable representation (one time). Use
.map()
. - Do the sorting with
.sort()
.
The values will be put in a lexicographical order. - Translate the sorted dates back into original representation.
This will guarantee that each date is translated at most twice, which makes the entire solution more performant for large N
s.
Also, Notice that steps #1 and #3 can use same exact implementation, which I extracted.
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
Produces result:
["31-12-2017", "01-01-2018", "02-01-2018", "01-02-2018"]
Little note. I think, that from the "big O" point of view we haven't improve the algorithm. Since .map(reverseDateRepresentation)
is $O(n)$, the performance of the entire solution is limited by the .sort()
(which is probably $O(n * log n)$). The way we're potentially improving solution is by making sure that the constants in our "big O" cost are as small as we can achieve.
Nevertheless, if we'd put the performance as top criteria of the solution, I'd learn as much as I can about the real data being processed; as well as conducted a thorough performance test.
In real life scenario, however, I personally never put performance above readability, because I believe that lack of readability is eventually the same thing as lack of correctness ...and correctness is almost always more important than performance (few exceptions are known though).
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
I'm not quite sure I understand what's happening here, How doesString.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?
â Mark Adel
Jan 4 at 5:58
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even theString.localeCompare
is not needed. We can just have.sort()
without any arguments, sinceString.localeCompare
is default
â Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
 |Â
show 7 more comments
up vote
3
down vote
Looking at your update answer, I would like to offer a couple points. You could minimize the amount of 'custom' logic by using some bult-in functions. For example, your comparisons to determine which integer to return is functionally the same as String.prototype.localeCompare(). Instead of if
/else
s you could write return date1.localeCompare(date2);
.
Also, at the start of your comparison function, in plain English you are essentially joining the array, but in reverse order. Therefore, why not utilize join
and reverse
? In fact, you could knock out the whole string preparation in a one-liner: date1.split('-').reverse().join('')
.
So the updated function would look like:
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('');
date2 = date2.split('-').reverse().join('');
return date1.localeCompare(date2);
);
1
Doingdate.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.
â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omitString.localeCompare
and just use.sort()
due to sort's default behavior.
â csp713
Jan 4 at 5:53
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
add a comment |Â
up vote
3
down vote
Simply compare the characters in order from most significant to least significant:
let indices = [ 6, 7, 8, 9, 3, 4, 0, 1 ];
var dates = ["02-02-2018", "02-01-2018", "01-02-2018", "01-01-2018", "12-31-2017" ];
dates.sort((a, b) =>
var r = 0;
indices.find(i => r = a.charCodeAt(i) - b.charCodeAt(i));
return r;
);
For each comparison this examines the minimum number of characters. Hard to imagine any other solution being faster, except maybe using a for loop instead of find.
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
 |Â
show 2 more comments
up vote
2
down vote
As the code is reviewed in other answers, I'll suggest you to different approach.
let getTimestamp = str => +new Date(...str.split('-').reverse());
dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
The function getTimestamp
will give the timestamp from the given string. This timestamp can be used in the sort
function for comparing with other dates.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
References:
Date
Array#sort
...
Spread syntax
Which way is more performant? How do I measure that?
To measure the performace, you may use jsperf.com. Or simply, use console.time
as shown in the demo.
That's nice! But why not usenew Date().getTime()
instead of+new Date()
which looks hacky.
â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can usegetTime()
as well, it is readable.+
is short.
â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
UPDATE: You can run performance tests I prepared based on various code samples from the answers to this question: https://jsperf.com/cr-se-date-array-sorting/1. When I ran them, I see that my code is second best performing. The best is the one by @Kevin Cline (up voted!).
Here's my take on it. The following code uses the same idea about the string representation of date that is directly comparable for sorting.
It is not possible to tell in advance how performant will this solution be compared to one you presented above. It all depends a lot on how many dates are being sorted. If you deal with tons of dates, there will be many more invocations to the arrow function we're passing to sort(...)
. Therefore, it's not good to keep translating the date via split()
every time our arrow function is being used.
Instead, I recommend three steps:
- Translate dates into a sortable representation (one time). Use
.map()
. - Do the sorting with
.sort()
.
The values will be put in a lexicographical order. - Translate the sorted dates back into original representation.
This will guarantee that each date is translated at most twice, which makes the entire solution more performant for large N
s.
Also, Notice that steps #1 and #3 can use same exact implementation, which I extracted.
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
Produces result:
["31-12-2017", "01-01-2018", "02-01-2018", "01-02-2018"]
Little note. I think, that from the "big O" point of view we haven't improve the algorithm. Since .map(reverseDateRepresentation)
is $O(n)$, the performance of the entire solution is limited by the .sort()
(which is probably $O(n * log n)$). The way we're potentially improving solution is by making sure that the constants in our "big O" cost are as small as we can achieve.
Nevertheless, if we'd put the performance as top criteria of the solution, I'd learn as much as I can about the real data being processed; as well as conducted a thorough performance test.
In real life scenario, however, I personally never put performance above readability, because I believe that lack of readability is eventually the same thing as lack of correctness ...and correctness is almost always more important than performance (few exceptions are known though).
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
I'm not quite sure I understand what's happening here, How doesString.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?
â Mark Adel
Jan 4 at 5:58
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even theString.localeCompare
is not needed. We can just have.sort()
without any arguments, sinceString.localeCompare
is default
â Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
 |Â
show 7 more comments
up vote
8
down vote
accepted
UPDATE: You can run performance tests I prepared based on various code samples from the answers to this question: https://jsperf.com/cr-se-date-array-sorting/1. When I ran them, I see that my code is second best performing. The best is the one by @Kevin Cline (up voted!).
Here's my take on it. The following code uses the same idea about the string representation of date that is directly comparable for sorting.
It is not possible to tell in advance how performant will this solution be compared to one you presented above. It all depends a lot on how many dates are being sorted. If you deal with tons of dates, there will be many more invocations to the arrow function we're passing to sort(...)
. Therefore, it's not good to keep translating the date via split()
every time our arrow function is being used.
Instead, I recommend three steps:
- Translate dates into a sortable representation (one time). Use
.map()
. - Do the sorting with
.sort()
.
The values will be put in a lexicographical order. - Translate the sorted dates back into original representation.
This will guarantee that each date is translated at most twice, which makes the entire solution more performant for large N
s.
Also, Notice that steps #1 and #3 can use same exact implementation, which I extracted.
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
Produces result:
["31-12-2017", "01-01-2018", "02-01-2018", "01-02-2018"]
Little note. I think, that from the "big O" point of view we haven't improve the algorithm. Since .map(reverseDateRepresentation)
is $O(n)$, the performance of the entire solution is limited by the .sort()
(which is probably $O(n * log n)$). The way we're potentially improving solution is by making sure that the constants in our "big O" cost are as small as we can achieve.
Nevertheless, if we'd put the performance as top criteria of the solution, I'd learn as much as I can about the real data being processed; as well as conducted a thorough performance test.
In real life scenario, however, I personally never put performance above readability, because I believe that lack of readability is eventually the same thing as lack of correctness ...and correctness is almost always more important than performance (few exceptions are known though).
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
I'm not quite sure I understand what's happening here, How doesString.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?
â Mark Adel
Jan 4 at 5:58
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even theString.localeCompare
is not needed. We can just have.sort()
without any arguments, sinceString.localeCompare
is default
â Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
 |Â
show 7 more comments
up vote
8
down vote
accepted
up vote
8
down vote
accepted
UPDATE: You can run performance tests I prepared based on various code samples from the answers to this question: https://jsperf.com/cr-se-date-array-sorting/1. When I ran them, I see that my code is second best performing. The best is the one by @Kevin Cline (up voted!).
Here's my take on it. The following code uses the same idea about the string representation of date that is directly comparable for sorting.
It is not possible to tell in advance how performant will this solution be compared to one you presented above. It all depends a lot on how many dates are being sorted. If you deal with tons of dates, there will be many more invocations to the arrow function we're passing to sort(...)
. Therefore, it's not good to keep translating the date via split()
every time our arrow function is being used.
Instead, I recommend three steps:
- Translate dates into a sortable representation (one time). Use
.map()
. - Do the sorting with
.sort()
.
The values will be put in a lexicographical order. - Translate the sorted dates back into original representation.
This will guarantee that each date is translated at most twice, which makes the entire solution more performant for large N
s.
Also, Notice that steps #1 and #3 can use same exact implementation, which I extracted.
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
Produces result:
["31-12-2017", "01-01-2018", "02-01-2018", "01-02-2018"]
Little note. I think, that from the "big O" point of view we haven't improve the algorithm. Since .map(reverseDateRepresentation)
is $O(n)$, the performance of the entire solution is limited by the .sort()
(which is probably $O(n * log n)$). The way we're potentially improving solution is by making sure that the constants in our "big O" cost are as small as we can achieve.
Nevertheless, if we'd put the performance as top criteria of the solution, I'd learn as much as I can about the real data being processed; as well as conducted a thorough performance test.
In real life scenario, however, I personally never put performance above readability, because I believe that lack of readability is eventually the same thing as lack of correctness ...and correctness is almost always more important than performance (few exceptions are known though).
UPDATE: You can run performance tests I prepared based on various code samples from the answers to this question: https://jsperf.com/cr-se-date-array-sorting/1. When I ran them, I see that my code is second best performing. The best is the one by @Kevin Cline (up voted!).
Here's my take on it. The following code uses the same idea about the string representation of date that is directly comparable for sorting.
It is not possible to tell in advance how performant will this solution be compared to one you presented above. It all depends a lot on how many dates are being sorted. If you deal with tons of dates, there will be many more invocations to the arrow function we're passing to sort(...)
. Therefore, it's not good to keep translating the date via split()
every time our arrow function is being used.
Instead, I recommend three steps:
- Translate dates into a sortable representation (one time). Use
.map()
. - Do the sorting with
.sort()
.
The values will be put in a lexicographical order. - Translate the sorted dates back into original representation.
This will guarantee that each date is translated at most twice, which makes the entire solution more performant for large N
s.
Also, Notice that steps #1 and #3 can use same exact implementation, which I extracted.
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
Produces result:
["31-12-2017", "01-01-2018", "02-01-2018", "01-02-2018"]
Little note. I think, that from the "big O" point of view we haven't improve the algorithm. Since .map(reverseDateRepresentation)
is $O(n)$, the performance of the entire solution is limited by the .sort()
(which is probably $O(n * log n)$). The way we're potentially improving solution is by making sure that the constants in our "big O" cost are as small as we can achieve.
Nevertheless, if we'd put the performance as top criteria of the solution, I'd learn as much as I can about the real data being processed; as well as conducted a thorough performance test.
In real life scenario, however, I personally never put performance above readability, because I believe that lack of readability is eventually the same thing as lack of correctness ...and correctness is almost always more important than performance (few exceptions are known though).
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
const reverseDateRepresentation = date =>
let parts = date.split('-');
return `$parts[2]-$parts[1]-$parts[0]`;
;
const sortedDates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017']
.map(reverseDateRepresentation)
.sort()
.map(reverseDateRepresentation);
console.log(sortedDates);
edited Jan 4 at 19:31
answered Jan 4 at 5:33
Igor Soloydenko
2,697827
2,697827
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
I'm not quite sure I understand what's happening here, How doesString.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?
â Mark Adel
Jan 4 at 5:58
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even theString.localeCompare
is not needed. We can just have.sort()
without any arguments, sinceString.localeCompare
is default
â Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
 |Â
show 7 more comments
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
I'm not quite sure I understand what's happening here, How doesString.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?
â Mark Adel
Jan 4 at 5:58
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even theString.localeCompare
is not needed. We can just have.sort()
without any arguments, sinceString.localeCompare
is default
â Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
I don't think this could be any better, Thanks!
â Mark Adel
Jan 4 at 5:44
1
1
I'm not quite sure I understand what's happening here, How does
String.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?â Mark Adel
Jan 4 at 5:58
I'm not quite sure I understand what's happening here, How does
String.localeCompare
function know that it should compare the first argument with the second one, not the opposite? Is that the default behavior?â Mark Adel
Jan 4 at 5:58
1
1
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even the
String.localeCompare
is not needed. We can just have .sort()
without any arguments, since String.localeCompare
is defaultâ Igor Soloydenko
Jan 4 at 6:00
@MarkAdel yeah, that's how functions work in JavaScript. But scp713 made a good point. Even the
String.localeCompare
is not needed. We can just have .sort()
without any arguments, since String.localeCompare
is defaultâ Igor Soloydenko
Jan 4 at 6:00
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Awesome! You can edit your answer now to reflect his suggestion.
â Mark Adel
Jan 4 at 6:04
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
Read and fully understood the note, it makes sense. Thank you for your time!
â Mark Adel
Jan 4 at 6:12
 |Â
show 7 more comments
up vote
3
down vote
Looking at your update answer, I would like to offer a couple points. You could minimize the amount of 'custom' logic by using some bult-in functions. For example, your comparisons to determine which integer to return is functionally the same as String.prototype.localeCompare(). Instead of if
/else
s you could write return date1.localeCompare(date2);
.
Also, at the start of your comparison function, in plain English you are essentially joining the array, but in reverse order. Therefore, why not utilize join
and reverse
? In fact, you could knock out the whole string preparation in a one-liner: date1.split('-').reverse().join('')
.
So the updated function would look like:
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('');
date2 = date2.split('-').reverse().join('');
return date1.localeCompare(date2);
);
1
Doingdate.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.
â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omitString.localeCompare
and just use.sort()
due to sort's default behavior.
â csp713
Jan 4 at 5:53
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
add a comment |Â
up vote
3
down vote
Looking at your update answer, I would like to offer a couple points. You could minimize the amount of 'custom' logic by using some bult-in functions. For example, your comparisons to determine which integer to return is functionally the same as String.prototype.localeCompare(). Instead of if
/else
s you could write return date1.localeCompare(date2);
.
Also, at the start of your comparison function, in plain English you are essentially joining the array, but in reverse order. Therefore, why not utilize join
and reverse
? In fact, you could knock out the whole string preparation in a one-liner: date1.split('-').reverse().join('')
.
So the updated function would look like:
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('');
date2 = date2.split('-').reverse().join('');
return date1.localeCompare(date2);
);
1
Doingdate.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.
â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omitString.localeCompare
and just use.sort()
due to sort's default behavior.
â csp713
Jan 4 at 5:53
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Looking at your update answer, I would like to offer a couple points. You could minimize the amount of 'custom' logic by using some bult-in functions. For example, your comparisons to determine which integer to return is functionally the same as String.prototype.localeCompare(). Instead of if
/else
s you could write return date1.localeCompare(date2);
.
Also, at the start of your comparison function, in plain English you are essentially joining the array, but in reverse order. Therefore, why not utilize join
and reverse
? In fact, you could knock out the whole string preparation in a one-liner: date1.split('-').reverse().join('')
.
So the updated function would look like:
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('');
date2 = date2.split('-').reverse().join('');
return date1.localeCompare(date2);
);
Looking at your update answer, I would like to offer a couple points. You could minimize the amount of 'custom' logic by using some bult-in functions. For example, your comparisons to determine which integer to return is functionally the same as String.prototype.localeCompare(). Instead of if
/else
s you could write return date1.localeCompare(date2);
.
Also, at the start of your comparison function, in plain English you are essentially joining the array, but in reverse order. Therefore, why not utilize join
and reverse
? In fact, you could knock out the whole string preparation in a one-liner: date1.split('-').reverse().join('')
.
So the updated function would look like:
dates.sort((date1, date2) =>
date1 = date1.split('-').reverse().join('');
date2 = date2.split('-').reverse().join('');
return date1.localeCompare(date2);
);
edited Jan 4 at 5:37
answered Jan 4 at 5:21
csp713
1313
1313
1
Doingdate.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.
â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omitString.localeCompare
and just use.sort()
due to sort's default behavior.
â csp713
Jan 4 at 5:53
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
add a comment |Â
1
Doingdate.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.
â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omitString.localeCompare
and just use.sort()
due to sort's default behavior.
â csp713
Jan 4 at 5:53
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
1
1
Doing
date.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.â Igor Soloydenko
Jan 4 at 5:35
Doing
date.split('-').reverse().join('')
on each invocation to the sort arrow function is too costly. See my answer with an alternative.â Igor Soloydenko
Jan 4 at 5:35
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omit
String.localeCompare
and just use .sort()
due to sort's default behavior.â csp713
Jan 4 at 5:53
@Igor Soloydenko I can't comment on your answer (too low rep) but now that I think about it, you could omit
String.localeCompare
and just use .sort()
due to sort's default behavior.â csp713
Jan 4 at 5:53
1
1
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
Sure thing. One last thing is that the Array.prototype.sort() docs say that "If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element", it doesn't mention localeCompare specifically
â csp713
Jan 4 at 6:12
add a comment |Â
up vote
3
down vote
Simply compare the characters in order from most significant to least significant:
let indices = [ 6, 7, 8, 9, 3, 4, 0, 1 ];
var dates = ["02-02-2018", "02-01-2018", "01-02-2018", "01-01-2018", "12-31-2017" ];
dates.sort((a, b) =>
var r = 0;
indices.find(i => r = a.charCodeAt(i) - b.charCodeAt(i));
return r;
);
For each comparison this examines the minimum number of characters. Hard to imagine any other solution being faster, except maybe using a for loop instead of find.
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
 |Â
show 2 more comments
up vote
3
down vote
Simply compare the characters in order from most significant to least significant:
let indices = [ 6, 7, 8, 9, 3, 4, 0, 1 ];
var dates = ["02-02-2018", "02-01-2018", "01-02-2018", "01-01-2018", "12-31-2017" ];
dates.sort((a, b) =>
var r = 0;
indices.find(i => r = a.charCodeAt(i) - b.charCodeAt(i));
return r;
);
For each comparison this examines the minimum number of characters. Hard to imagine any other solution being faster, except maybe using a for loop instead of find.
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
 |Â
show 2 more comments
up vote
3
down vote
up vote
3
down vote
Simply compare the characters in order from most significant to least significant:
let indices = [ 6, 7, 8, 9, 3, 4, 0, 1 ];
var dates = ["02-02-2018", "02-01-2018", "01-02-2018", "01-01-2018", "12-31-2017" ];
dates.sort((a, b) =>
var r = 0;
indices.find(i => r = a.charCodeAt(i) - b.charCodeAt(i));
return r;
);
For each comparison this examines the minimum number of characters. Hard to imagine any other solution being faster, except maybe using a for loop instead of find.
Simply compare the characters in order from most significant to least significant:
let indices = [ 6, 7, 8, 9, 3, 4, 0, 1 ];
var dates = ["02-02-2018", "02-01-2018", "01-02-2018", "01-01-2018", "12-31-2017" ];
dates.sort((a, b) =>
var r = 0;
indices.find(i => r = a.charCodeAt(i) - b.charCodeAt(i));
return r;
);
For each comparison this examines the minimum number of characters. Hard to imagine any other solution being faster, except maybe using a for loop instead of find.
edited Jan 4 at 9:26
answered Jan 4 at 8:41
kevin cline
31516
31516
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
 |Â
show 2 more comments
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Thank you, but I added the question under JavaScript tag, I expect the answers to be in JavaScript. I'm confused with this Java code, I'd appreciate it if you re-wrote it in JavaScript.
â Mark Adel
Jan 4 at 9:24
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
Sorry I missed that. I have replaced the original code with tested Javascript.
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's simpler in Javascript :-)
â kevin cline
Jan 4 at 9:30
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
It's clear now, That's a smart approach I like it! Check Igor's answer too it's very efficient.
â Mark Adel
Jan 4 at 11:54
1
1
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
I implemented it using a for loop and ran a performance test, It's ~4 times faster! Check jsperf.com/date-array-sorting/1
â Mark Adel
Jan 4 at 22:06
 |Â
show 2 more comments
up vote
2
down vote
As the code is reviewed in other answers, I'll suggest you to different approach.
let getTimestamp = str => +new Date(...str.split('-').reverse());
dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
The function getTimestamp
will give the timestamp from the given string. This timestamp can be used in the sort
function for comparing with other dates.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
References:
Date
Array#sort
...
Spread syntax
Which way is more performant? How do I measure that?
To measure the performace, you may use jsperf.com. Or simply, use console.time
as shown in the demo.
That's nice! But why not usenew Date().getTime()
instead of+new Date()
which looks hacky.
â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can usegetTime()
as well, it is readable.+
is short.
â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
add a comment |Â
up vote
2
down vote
As the code is reviewed in other answers, I'll suggest you to different approach.
let getTimestamp = str => +new Date(...str.split('-').reverse());
dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
The function getTimestamp
will give the timestamp from the given string. This timestamp can be used in the sort
function for comparing with other dates.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
References:
Date
Array#sort
...
Spread syntax
Which way is more performant? How do I measure that?
To measure the performace, you may use jsperf.com. Or simply, use console.time
as shown in the demo.
That's nice! But why not usenew Date().getTime()
instead of+new Date()
which looks hacky.
â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can usegetTime()
as well, it is readable.+
is short.
â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
add a comment |Â
up vote
2
down vote
up vote
2
down vote
As the code is reviewed in other answers, I'll suggest you to different approach.
let getTimestamp = str => +new Date(...str.split('-').reverse());
dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
The function getTimestamp
will give the timestamp from the given string. This timestamp can be used in the sort
function for comparing with other dates.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
References:
Date
Array#sort
...
Spread syntax
Which way is more performant? How do I measure that?
To measure the performace, you may use jsperf.com. Or simply, use console.time
as shown in the demo.
As the code is reviewed in other answers, I'll suggest you to different approach.
let getTimestamp = str => +new Date(...str.split('-').reverse());
dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
The function getTimestamp
will give the timestamp from the given string. This timestamp can be used in the sort
function for comparing with other dates.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
References:
Date
Array#sort
...
Spread syntax
Which way is more performant? How do I measure that?
To measure the performace, you may use jsperf.com. Or simply, use console.time
as shown in the demo.
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
let dates = ['01-02-2018', '02-01-2018', '01-01-2018', '31-12-2017'];
console.time('tushar');
let getTimestamp = str => +new Date(...str.split('-').reverse());
let sortedDates = dates.sort((a, b) => getTimestamp(a) - getTimestamp(b));
console.log(sortedDates);
console.timeEnd('tushar');
edited Jan 4 at 6:28
answered Jan 4 at 6:22
Tushar
2,71011224
2,71011224
That's nice! But why not usenew Date().getTime()
instead of+new Date()
which looks hacky.
â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can usegetTime()
as well, it is readable.+
is short.
â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
add a comment |Â
That's nice! But why not usenew Date().getTime()
instead of+new Date()
which looks hacky.
â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can usegetTime()
as well, it is readable.+
is short.
â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
That's nice! But why not use
new Date().getTime()
instead of +new Date()
which looks hacky.â Mark Adel
Jan 4 at 6:40
That's nice! But why not use
new Date().getTime()
instead of +new Date()
which looks hacky.â Mark Adel
Jan 4 at 6:40
@MarkAdel Yes. You can use
getTime()
as well, it is readable. +
is short.â Tushar
Jan 4 at 7:11
@MarkAdel Yes. You can use
getTime()
as well, it is readable. +
is short.â Tushar
Jan 4 at 7:11
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
Unfortunately, string->Date parsing is costly, and it will limit the performance of the end result.
â Igor Soloydenko
Jan 4 at 19:36
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
@IgorSoloydenko Yes. I saw the comparison in your answer.
â Tushar
Jan 5 at 4:33
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184248%2fsorting-dates-in-this-format-dd-mm-yyyy%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
You don't need to parse the strings at all. A sort on characters is sufficient. If the dates were stored in the proper order (ISO format, YYYY-MM-DD), then a direct string comparison would work. Here you can compare strings
date1[2]
todate2[2]
, if those are equal, compare[1]
, etc.â Cris Luengo
Jan 4 at 4:37
Right, but in my case, the days come first. So this comparison
'31-12-2017' < '02-01-2018';
will return false.â Mark Adel
Jan 4 at 4:47
Do you suggest reordering the date to be in this format (YYYY-MM-DD) and then comparing the strings?
â Mark Adel
Jan 4 at 4:53
11
Don't store dates as strings within your application. At the earliest possible time, convert them to proper
Date
objects, and if a string representation is necessary, convert them to aString
at the latest possible time. This way, you have the benefit of easy handling all throughout your applicaiton. This code would just bedates.sort ( (a, b) => return a - b );
â Alexander
Jan 4 at 7:26
1
@Alexander I hate JavaScript date implementation and normally am staying away from them. It's much better IMO, to use ISO 8601 date representation for as long as possible (which is until you need to do date arithmetic) --
YYYY-MM-DDTHH:mm:ss
. And when it comes to date arithmetic, use a library like moment.js or date-fns, anything but the damn native Date with horrible API.â Igor Soloydenko
Jan 4 at 18:26