Reputation: 622
I have a fairly classic case of sorting on many fields at the same time. What is difficult for me is passing data with fields for sorting from a separate array.
const arrayToSort = [
{
Country: "Cyprus",
Date: new Date(2001, 0, 1),
CreateBy: "William",
},
{
Country: "Belarus",
Date: new Date(1999, 0, 1),
CreateBy: "Yuliana",
},
{
Country: "Denmark",
Date: new Date(2019, 0, 1),
CreateBy: "Ava",
},
{
Country: "Albania",
Date: new Date(2000, 0, 1),
CreateBy: "Zachary",
}
];
const sortFields = ["Country", "CreateBy", "Date"];
const descending = [true, false, true];
const sortedArray = arrayToSort.sort((a, b) => {
return arrayToSort.forEach((field, index) => {
const isDate = !isNaN(Date.parse(a[field]));
if (isDate) {
const dateA = new Date(a[field]).getTime();
const dateB = new Date(b[field]).getTime();
if (descending[index] && dateA < dateB) {
return -1;
}
if (dateA > dateB) {
return 1;
}
return 0;
}
if (descending[index] && a[field] < b[field]) {
return -1;
}
if (a[field] > b[field]) {
return 1;
}
return 0;
})
})
console.log(sortedArray);
If I had a static number of elements, I would know what to do. What if I do not know the number of fields in the array? Should I use forEach here? When I console.log sortedArray
, nothing changed.
Upvotes: 0
Views: 195
Reputation: 136074
I'd start off with a function which sorts 2 objects by a field and descending bool
const sortBy = (a,b,field,desc) => {
if(a[field]<b[field]) return desc ? 1 : -1
else if(a[field]>b[field]) return desc ? -1 : 1
else return 0;
};
You can then use this in a loop over your sortFields
(and descending
) arrays:
const arrayToSort = [
{
Country: "Cyprus",
Date: new Date(2001, 0, 1),
CreateBy: "William",
},
{
Country: "Belarus",
Date: new Date(1999, 0, 1),
CreateBy: "Yuliana",
},
{
Country: "Denmark",
Date: new Date(2019, 0, 1),
CreateBy: "Ava",
},
{
Country: "Albania",
Date: new Date(2000, 0, 1),
CreateBy: "Zachary",
}
];
const sortFields = ["Country", "CreateBy", "Date"];
const descending = [true, false, true];
const sortBy = (a,b,field,desc) => {
if(a[field]<b[field]) return desc ? 1 : -1
else if(a[field]>b[field]) return desc ? -1 : 1
else return 0;
};
const result = arrayToSort.sort( (a,b) => {
for(var i=0;i<sortFields.length;i++){
var res = sortBy(a,b, sortFields[i], descending[i]);
if(res != 0) return res;
}
return 0;
})
console.log(result);
Upvotes: 1