Home > Blockchain >  Move elements with specific values to bottom of sorted array in js
Move elements with specific values to bottom of sorted array in js

Time:01-11

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)));
  • Related