Reputation: 35557
I am trying to sort an array, on a string date, and I am having some issues with it.
My array is called: myArray and has the following sample info:
0: {…}
deployed_date: "29/01/2019 14:08:44"
last_restored_date: "11/01/2019 11:22:22"
1: {…}
deployed_date: "29/01/2019 14:08:19"
2: {…}
deployed_date: "29/01/2019 11:34:23"
3: {…}
deployed_date: "11/02/2019 11:24:33"
4: {…}
deployed_date: "11/02/2019 11:24:24"
last_restored_date: "11/01/2019 11:25:42"
I have used both Lodash and native JavaScript sorting, but unfortunately I am not able to sort on this deployed_date alone in descending order.
FYI, I am also using momentjs:
myArray[key].deployed_date = moment(value.deployed_date,'YYYYMMDDHHmmss').format('DD/MM/YYYY HH:mm:ss');
I have used:
_.orderBy(myArray, ['deployed_date'],['desc'])
//lodash
as well as
myArray.sort()
The order is appearing as in my array above.
I'm not sure if it's to do with the fact that array indexes 1,2 and 3 do not have a last_restored_date
value but for some reason, the array is not sorted correctly by deployed_date desc.
The result I expect is:
11/02/2019 11:24:33
11/02/2019 11:24:24
29/01/2019 14:08:44
29/01/2019 14:08:19
29/01/2019 11:34:23
How can I achieve the expected result order shown here?
Upvotes: 0
Views: 969
Reputation: 1329
The way I see it, your usage of lodash’s orderBy is good and it should have ordered your data as expected. What’s causing you issues is that you're sorting strings not dates and your strings are in the format DD/MM/YYYY which is not ideal if you want to sort them: 01/01/2019 is « before » 31/12/2018 (although nonsensical).
What you can do: 1/ you can either have Date or Moment data instead of strings 2/ or format your dates as YYYY-MM-DD ... etc 3/ or pass a function to the sorting function ˋ_.orderBy(myArray, [d => moment(d.deployed_data, ...)], ['desc'])`
Upvotes: 0
Reputation: 76
You can use map on the resulting array like this to obtain the expected result
let new_arr = foo.map( (obj) => {
return obj.deployed_date;
);
Hope it makes sense
Upvotes: 0
Reputation: 4116
const toDate = str => {
const [d, t] = str.split(' ')
return new Date(`${d.split('/').reverse().join('-')}T${t}Z`).getTime();
};
const compareByDate = (x, y) => toDate(y.deployed_date) - toDate(x.deployed_date);
const arr = [
{deployed_date: "29/01/2019 14:08:44"},
{deployed_date: "29/01/2019 14:08:19"},
{deployed_date: "29/01/2019 11:34:23"},
{deployed_date: "11/02/2019 11:24:33"},
{deployed_date: "11/02/2019 11:24:24"}
];
arr.sort(compareByDate);
console.log(arr);
Date.getTime()
) to facilitate comparisons. Use the Date constructor to change the string into a Date. Then convert that date into milliseconds(x, y) => y - x;
deployed_date
The ISO format we want to use is YYYY-MM-DDTHH:MM:SSZ
. And since we have 29/01/2019 14:08:44
we need to do some processing.
' '
to separate time and date'/'
and reverse the array, since we want YYYY-MM_DD
. Then join
using the '-'
characternew Date(...)
then convert it into milliseconds using Date.getMilliseconds()
Upvotes: 0
Reputation: 17190
One solution is to map your dates to standard format when comparing the deployed_date
of two objects using String::localeCompare():
const myArray = [
{deployed_date: "29/01/2019 14:08:44", last_restored_date: "11/01/2019 11:22:22"},
{deployed_date: "29/01/2019 14:08:19"},
{deployed_date: "29/01/2019 11:34:23"},
{deployed_date: "11/02/2019 11:24:33"},
{deployed_date: "11/02/2019 11:24:24", last_restored_date: "11/01/2019 11:25:42"}
];
myArray.sort((a, b) =>
{
let [aDate, aHour] = a.deployed_date.split(" ");
let [bDate, bHour] = b.deployed_date.split(" ");
let [aDay, aMonth, aYear] = aDate.split("/");
let [bDay, bMonth, bYear] = bDate.split("/");
let newADate = `${aYear}/${aMonth}/${aDay} ${aHour}`;
let newBDate = `${bYear}/${bMonth}/${bDay} ${bHour}`;
return newBDate.localeCompare(newADate);
});
console.log(myArray);
Upvotes: 0
Reputation: 1896
Please use moment library to firstly format the date in 'DD/MM/YYYY HH:mm:ss' and below code will sort and returns result as you are looking for
x.sort((a,b)=>{
return moment(a,'DD/MM/YYY HH:mm:ss').isAfter(moment(b,'DD/MM/YYY HH:mm:ss')) ? -1 : 1
})
Upvotes: 1