0

I have an array of objects, each object has a "condition" property. It can either be a single value string ex "Original", or a multiple comma separated values string ex "Original, Brand new". i see this question also , but in that not tell about sort for given order

[
  {id: 1, condition: "Original"},
  {id: 2, condition: "Original, Used"},
  {id: 3, condition: "Used"},
  {id: 4, condition: "After market"},
  {id: 5, condition: "After Market,Used"},
  {id: 6, condition: "Used"},
  {id: 7, condition: "Used, Original"},
]

I want to sort my array based on the "condition" property and the sort function should accept an argument being an array of keys to ask for a specific order:

Given the following keys as input ["Original","Used","After Market"], the sort function would return this array:

[
  {id: 1, condition: "Original"},
  {id: 2, condition: "Original, Used"},
  {id: 7, condition: "Used, Original"}
  {id: 3, condition: "Used"},
  {id: 6, condition: "Used"},
  {id: 5, condition: "After Market,Used"},
  {id: 4, condition: "After market"},
]
Hassan Amjad
  • 399
  • 1
  • 6
  • 20
  • 1
    Hi! Please read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Your best bet here is to do your research, [search](/help/searching) for related topics on SO, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] of your attempt and say specifically where you're stuck. People will be glad to help. Separately, it's not at all clear from your question what order it is you want, or really what the overall data looks like. Code is worth 1024 words. – T.J. Crowder Oct 26 '19 at 11:09
  • Can you please update your question with what exactly output you want? – bhuvnesh pattnaik Oct 26 '19 at 11:34
  • @bhuvneshpattnaik i add the expected output – Hassan Amjad Oct 26 '19 at 11:45
  • Check this answer: https://stackoverflow.com/questions/14872554/sorting-on-a-custom-order – Braulio Oct 26 '19 at 11:50
  • i already checked that @Braulio in that question there is only one value in string but in my case it can be more then one – Hassan Amjad Oct 26 '19 at 11:52
  • Possible duplicate of [How to define custom sort function in javascript?](https://stackoverflow.com/questions/5002848/how-to-define-custom-sort-function-in-javascript) – Dexygen Oct 26 '19 at 12:30

3 Answers3

1

You can user compare function as an argument to Array.prorotype.sort. The compare function will check for first element in condition which will be either Original, Used, After Market and will return accordingly.

function(a,b){/* if you want a to come before b return -1 else return 1*/}

I am considering first element only to sort array, if you want to compare second elements when first element is same then you can write accordingly.

For example.

function compare(a,b){
    let order = ["Original","Used","After Market"];
    let conditionA = a.condition.split(",");
    let conditionB = b.condition.split(",");
    if(order.indexOf(conditionA[0]) < order.indexOf(conditionB[0])){
        return -1;
    }
    else if(order.indexOf(conditionA[0]) > order.indexOf(conditionB[0]) ){
        return 1;   
    } 
    else{
        /*compare next elements in conditionA and conditionB array if they exists */
    }

}

I would recommend you to go through article

let arr = [
{id:1,condition:"Original"},
{id:2,condition:"Original, Used"},
{id:3,condition:"Used"},
{id:4,condition:"After Market"},
{id:5,condition:"After Market,Used"},
{id:6,condition:"Used"},
{id:7,condition:"Used, Original"},
]



function compare(a,b){
  let order = ["Original","Used","After Market"];
  let conditionA = a.condition.split(",");
  let conditionB = b.condition.split(",");
  if(order.indexOf(conditionA[0]) <= order.indexOf(conditionB[0])){
    return -1;
  }
  else{
    return 1; 
  } 

}

console.log(arr.sort(compare))
Akshay Bande
  • 2,491
  • 2
  • 12
  • 29
0

You can set an order system original 1 used 2 after market 3 then calculate the score which is the mean value of the condition based on the score system. The best is the one with closest score to 1.

const orders = {
  "original":1,
  "used":2,
  "aftermarket":3
};

const input = [
    {id:1,condition:"Original"},
    {id:2,condition:"Original, Used"},
    {id:3,condition:"Used"},
    {id:4,condition:"After market"},
    {id:5,condition:"After Market,Used"},
    {id:6,condition:"Used"},
    {id:7,condition:"Used, Original"},
    ];

const getScore = (a,c,i,arr) => {
  return a + orders[c]/arr.length;
}

const output = input
  .map( e=> ({...e, score: e.condition.replace(/ /g,'')
    .toLowerCase()
    .split(',')
    .reduce(getScore,0)}))
  .sort((a,b) => a.score - b.score )
console.log(output);
Melchia
  • 22,578
  • 22
  • 103
  • 117
0

I think You can make custom function marketSort() and use this function for your use. It will give you expected result which you needed

function marketSort(a) {
let b = [];
let c = a.filter(i => i.condition.toLowerCase().includes("original") && !i.condition.toLowerCase().includes("used"));
b = b.concat(c);
c = a.filter(i => i.condition.toLowerCase().includes("original") && i.condition.toLowerCase().includes("used"));
b = b.concat(c);
c = a.filter(i => i.condition.toLowerCase().includes("used") && !i.condition.toLowerCase().includes("after market"));
b = b.concat(c);
c = a.filter(i => i.condition.toLowerCase().includes("used") && i.condition.toLowerCase().includes("after market"));
b = b.concat(c);
c = a.filter(i => i.condition.toLowerCase().includes("after market"));
b = b.concat(c);
return b;
}

let a = [
    {id:1,condition:"Original"},
    {id:2,condition:"Original, Used"},
    {id:3,condition:"Used"},
    {id:4,condition:"After market"},
    {id:5,condition:"After Market,Used"},
    {id:6,condition:"Used"},
    {id:7,condition:"Used, Original"},
    ];

console.log(marketSort(a));
bhuvnesh pattnaik
  • 1,365
  • 7
  • 14