I have an array of objects that I want to sort by specific values, f.x. price. The objects have an item called "status"
that can have either "available", "reserved" or "occupied"
.
The sorting on f.x price works perfectly fine, but what I am trying to achieve is to take the sorted array and take out the items that have a status other than "available"
and put them to the bottom of the array, with "reserved"
before "occupied"
, but also sorted by their price.
So when I have a random sorted array
[{
id: 1619,
address: "Street 1",
rooms: 3,
price: 10695,
status: "Available",
},
{
id: 1620,
address: "Street 5",
rooms: 3,
price: 7859,
status: "Available",
},
{
id: 1626,
address: "Street 7",
rooms: 3,
price: 8595,
status: "Reserved",
},
{
id: 1624,
address: "Street 11",
rooms: 4,
price: 9795,
status: "Occupied",
},
{
id: 1624,
address: "Street 3",
rooms: 4,
price: 2856,
status: "Reserved",
}]
and use
function sortList(property, list, order) {
list.sort(function (a, b) {
if (a[property] === b[property]) {
return 0;
}
const va = a[property];
const vb = b[property];
if (order === 'asc') {
return va < vb ? 1 : -1;
}
return va > vb ? 1 : -1;
});
}
sortList("price", list, "desc");
to sort it by price - this works fine. I then want to take that sorted list and put "Reserved" and "Occupied" to the bottom of the array - still sorted by price, so I end up with an array like this:
[{
id: 1620,
address: "Street 5",
rooms: 3,
price: 7859,
status: "Available",
},
{
id: 1619,
address: "Street 1",
rooms: 3,
price: 10695,
status: "Available",
},
{
id: 1624,
address: "Street 3",
rooms: 4,
price: 2856,
status: "Reserved",
},
{
id: 1626,
address: "Street 7",
rooms: 3,
price: 8595,
status: "Reserved",
},
{
id: 1624,
address: "Street 11",
rooms: 4,
price: 9795,
status: "Occupied",
}]
CodePudding user response:
Use array's sort function (list is your original array):
const l = list.sort( (a,b) => {
if(a.status === b.status) return a.price - b.price;
const x = a.status === "Available" ? 0 : a.status === "Reserved" ? 1 : 2;
const y = b.status === "Available" ? 0 : b.status === "Reserved" ? 1 : 2;
return x-y;
});
console.log(l);
Function just compares price if status is the same otherwise it compares statuses.
CodePudding user response:
Filter out the items you want, remove them from the list and then push them to the end of the list (after sorting).
const list = [{
id: 1619,
address: "Street 1",
rooms: 3,
price: 10695,
status: "Available",
},
{
id: 1620,
address: "Street 5",
rooms: 3,
price: 7859,
status: "Available",
},
{
id: 1626,
address: "Street 7",
rooms: 3,
price: 8595,
status: "Reserved",
},
{
id: 1624,
address: "Street 11",
rooms: 4,
price: 9795,
status: "Occupied",
},
{
id: 1624,
address: "Street 3",
rooms: 4,
price: 2856,
status: "Reserved",
}
];
function sortList(property, list, order) {
list.sort(function(a, b) {
if (a[property] === b[property]) {
return 0;
}
const va = a[property];
const vb = b[property];
if (order === 'asc') {
return va < vb ? 1 : -1;
}
return va > vb ? 1 : -1;
});
}
function extractItems(list) {
const extracted = list.filter(el => el.status == "Reserved" || el.status == "Occupied");
list = list.filter((el) => !extracted.includes(el));
list.push(extracted);
return list;
}
sortList("price", list, "desc");
newList = extractItems(list)
console.log(newList);
CodePudding user response:
It sounds like you need to sort the array twice. First sort by the price, and then sort by another array ['reserved', 'occupied', 'available']
;
Like so:
let arr = [{
id: 1619,
address: "Street 1",
rooms: 3,
price: 10695,
status: "Available",
},
{
id: 1620,
address: "Street 5",
rooms: 3,
price: 7859,
status: "Available",
},
{
id: 1626,
address: "Street 7",
rooms: 3,
price: 8595,
status: "Reserved",
},
{
id: 1624,
address: "Street 11",
rooms: 4,
price: 9795,
status: "Occupied",
},
{
id: 1624,
address: "Street 3",
rooms: 4,
price: 2856,
status: "Reserved",
}];
let sortArray = ['Reserved', 'Occupied', 'Available'];
console.log(arr.sort((a, b) => (a.price > b.price) ? 1 : -1).sort((a,b) => sortArray.indexOf(a.status) - sortArray.indexOf(b.status)));