Reputation: 119
I have an array of object such as
[{
time: "13:20",
key2: "",
key3: ""
}, {
time: "13:40",
key2: "",
key3: ""
}, {
time: "04:20",
key2: "",
key3: ""
}]
and I want them to sort according to time. I did some research on momentjs but I didn't found something useful.
The main problem I am facing is How to convert that time that I am getting into String format to some comparable format for sorting. Any kind of help will be appreciated.Thank you.
Upvotes: 4
Views: 80
Reputation: 13963
If your time strings are in the HH:MM
format, you can simply do a lexicographical sort with String.prototype.localeCompare():
const data = [
{ time: '13:20', key2: '', key3: '' },
{ time: '13:40', key2: '', key3: '' },
{ time: '04:20', key2: '', key3: '' },
{ time: '23:03', key2: '', key3: '' }
];
const ascending = [...data].sort((a, b) => a.time.localeCompare(b.time));
const descending = [...data].sort((a, b) => b.time.localeCompare(a.time));
console.log(JSON.stringify(ascending));
console.log(JSON.stringify(descending));
If your time strings do not follow this format, ie. may be specified as H
, HH
, HH:M
, HH:MM
..., then you can parse the string with RegExp.prototype.exec():
const data = [
{ time: '13:20', key2: '', key3: '' },
{ time: '13:40', key2: '', key3: '' },
{ time: '04:20', key2: '', key3: '' },
{ time: ' 4:25', key2: '', key3: '' },
{ time: '23:03', key2: '', key3: '' },
{ time: '14: 3', key2: '', key3: '' },
{ time: ' 2 ', key2: '', key3: '' },
];
const hourMinutes = str => /\s*(?<hh>\d*)\s*:?\s*(?<mm>\d*)\s*/.exec(str);
const toMinutes = ({ hh = 0, mm = 0 }) => (+hh) * 60 + (+mm);
const toTime = ({ time }) => toMinutes(hourMinutes(time).groups);
const ascending = [...data].sort((a, b) => toTime(a) - toTime(b));
const descending = [...data].sort((a, b) => toTime(b) - toTime(a));
console.log(JSON.stringify(ascending));
console.log(JSON.stringify(descending));
Upvotes: 2
Reputation: 24925
You can take following approach to sort it:
Benefit of having date based approach is that it will handle all time value cases. I have updated data to have second values as well for demonstration
var data = [{
time: "13:20",
key2: "",
key3: ""
}, {
time: "13:40",
key2: "",
key3: ""
}, {
time: "04:20:10",
key2: "",
key3: ""
}, {
time: "04:20:20",
key2: "",
key3: ""
}];
function getAddedTimeValue(time) {
const parts = [...time.split(':'), 0, 0, 0, 0].slice(0, 4);
const date = new Date();
date.setHours.apply(date, parts);
return date.getTime();
}
data.sort((a, b) => getAddedTimeValue(a.time) - getAddedTimeValue(b.time));
// For descending:
// data.sort((a, b) => getAddedTimeValue(b.time) - getAddedTimeValue(a.time));
console.log(data)
Upvotes: 2
Reputation: 36584
You make a same date for all the times. And then getTime()
and compare that
let arr = [{
time: "13:20",
key2: "",
key3: ""
}, {
time: "13:40",
key2: "",
key3: ""
}, {
time: "04:20",
key2: "",
key3: ""
}]
const toTime = (t) => new Date(`December 17, 1995 ${t}`).getTime();
arr.sort((a,b) => toTime(a.time) - toTime(b.time))
console.log(arr)
Upvotes: 3
Reputation: 30370
You could parse and sort the time
field of each item in a custom callback passed to Array#sort()
as shown below:
const input = [ { time : "13:20" , key2: "", key3: ""},{ time : "13:40" , key2: "", key3: ""},{ time : "04:20" , key2: "", key3: ""}];
const output = input.sort((a, b) => {
const [aHours, aMinutes] = a.time.split(':');
const [bHours, bMinutes] = b.time.split(':');
if(aHours < bHours) {
return -1;
}
else if(aHours > bHours) {
return 1;
}
else {
if(aMinutes < bMinutes) {
return -1;
}
else if(aMinutes > bMinutes) {
return 1;
}
}
return 0;
});
console.log(output);
Upvotes: 1
Reputation: 386654
You could get minutes of the given time and sort by this value.
const getMinutes = s => s.split(':').reduce((h, m) => h * 60 + m);
var array = [{ time: "13:20", key2: "", key3: "" }, { time: "13:40", key2: "", key3: "" }, { time: "04:20", key2: "", key3: "" }];
array.sort((a, b) => getMinutes(a.time) - getMinutes(b.time));
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 30739
You can simply get the first numeric part that is before :
and compare that for sorting and if the first part is same, then consider the second numeric part that is after :
Sort Ascending
var arr = [{
time: "13:20",
key2: "",
key3: ""
}, {
time: "13:40",
key2: "",
key3: ""
}, {
time: "04:20",
key2: "",
key3: ""
}];
arr.sort(function(a, b) {
var aSplit = a.time.split(':');
var bSplit = b.time.split(':');
return (aSplit[0] - bSplit[0] || aSplit[1] - bSplit[1]);
});
console.log(arr);
Sort Descending
var arr = [{
time: "13:20",
key2: "",
key3: ""
}, {
time: "13:40",
key2: "",
key3: ""
}, {
time: "04:20",
key2: "",
key3: ""
}];
arr.sort(function(a, b) {
var aSplit = a.time.split(':');
var bSplit = b.time.split(':');
return (bSplit[0] - aSplit[0] || bSplit[1] - aSplit[1]);
});
console.log(arr);
Upvotes: 1