1

I have an array, i need to sort the array based on one property if that exists.

const arr = [{
    "item_name": "Cake",
    "quantity": 1,
  },
  {
    "item_name": "Choclate",
    "out_of_stock_detail": {
      "out_of_stock_quantity": 1
    },
    "quantity": 3,

  }
]

let output = arr.sort((a, b) => {
  if (a.out_of_stock_detail) {
    return 1
  } else {
    return -1
  }
})

console.log(output)

Expected output what I am looking out to get.

const result = [{
    "item_name": "Choclate",
    "out_of_stock_detail": {
      "out_of_stock_quantity": 1
    },
    "quantity": 3,

  },
  {
    "item_name": "Cake",
    "quantity": 1,
  }
]
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
dev
  • 814
  • 10
  • 27
  • 2
    Property existence is checked with `a.hasOwnProperty("out_of_stock_detail")`. Checking `a.out_of_stock_detail` has different semantics. Why are you never checking `b`? Why are you never returning `0`? – Sebastian Simon Dec 02 '21 at 18:54
  • Didn't understood of checking with b and returning 0, can you help here not understanding what I am doing wrong here – dev Dec 02 '21 at 19:01
  • Does this answer your question? [How does Javascript's sort() work?](https://stackoverflow.com/questions/1494713/how-does-javascripts-sort-work) Read **all** answers there, – PM 77-1 Dec 02 '21 at 19:06
  • @de The [documentation](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description) describes how `sort` works. – Sebastian Simon Dec 02 '21 at 19:06

4 Answers4

2

Here's an option. Create a numeric value based on the existence of the property then return the comparison. I also added a second sort so highest quantities are first.

const arr = [{
    "item_name": "Cake",
    "quantity": 1,
  },
  {
    "item_name": "Choclate",
    "out_of_stock_detail": {
      "out_of_stock_quantity": 1
    },
    "quantity": 3,
  },
  {
    "item_name": "Vanilla",
    "out_of_stock_detail": {
      "out_of_stock_quantity": 1
    },
    "quantity": 9,
  }
]

let output = arr.sort((a, b) => {
  let aa = a.hasOwnProperty('out_of_stock_detail') ? 1 : -1
  let bb = b.hasOwnProperty('out_of_stock_detail') ? 1 : -1
  return bb - aa;
}).sort((a, b) => +b.quantity - +a.quantity)

console.log(output)
Kinglish
  • 23,358
  • 3
  • 22
  • 43
1

Just a slightly other approach by taking a boolean and taking the delta of it.

BTW, Array#sort sorts in situ (mutating the array).

const
    array = [{ item_name: "Cake", quantity: 1 }, { item_name: "Choclate", out_of_stock_detail: { out_of_stock_quantity: 1 }, quantity: 3 }];

array.sort((a, b) => 
    ('out_of_stock_detail' in b) - ('out_of_stock_detail' in a)
);

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

really strange code, but like this?

let output = arr.sort((a,b) => {
   if(a.out_of_stock_detail && !b.out_of_stock_detail){
    return -1 
  }else{
    return 1
  }
})

wouldn't it be better to separate those?

let outOfStock = arr.filter((item) => item.out_of_stock_detail);
let inStock = arr.filter((item) => !item.out_of_stock_detail);
TheWuif
  • 988
  • 6
  • 11
0

Didn't you just mix up the 1 and -1?

const arr =  [
        {
            "item_name": "Cake",
            "quantity": 1,
        },
        {
            "item_name": "Choclate",
            "out_of_stock_detail": {
                "out_of_stock_quantity": 1
            },
            "quantity": 3,
    
        }
    ]

let output = arr.sort((a,b) => {
   if(a.out_of_stock_detail){
    return -1 
  }else {
    return 1
  }
})

console.log(output)
Purple Man
  • 11
  • 2