最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sort array of object on a property but keep the objects first for which property is missing - Stack Overflow

programmeradmin4浏览0评论

Here is an example

testWidgetOrderSort = [
        { "_id": "name", "order": 1 },
        { "_id": "is", "order": 2 },
        { "_id": "my", "order": 0 },
        { "_id": "oh I would be very first" },
        { "_id": "adam", "order": 3 }

      ]

Here for the the object { "_id": "oh I would be very first" } does not have the property order so it should e first. And then the rest of the objects should be sorted according to the property "order" So after sorting it should be,

 output= [ { _id: 'oh I would be very first' },
      { _id: 'my', order: 0 },
      { _id: 'name', order: 1 },
      { _id: 'is', order: 2 },
      { _id: 'adam', order: 3 } ]

Here is an example

testWidgetOrderSort = [
        { "_id": "name", "order": 1 },
        { "_id": "is", "order": 2 },
        { "_id": "my", "order": 0 },
        { "_id": "oh I would be very first" },
        { "_id": "adam", "order": 3 }

      ]

Here for the the object { "_id": "oh I would be very first" } does not have the property order so it should e first. And then the rest of the objects should be sorted according to the property "order" So after sorting it should be,

 output= [ { _id: 'oh I would be very first' },
      { _id: 'my', order: 0 },
      { _id: 'name', order: 1 },
      { _id: 'is', order: 2 },
      { _id: 'adam', order: 3 } ]
Share Improve this question asked Aug 19, 2021 at 11:20 AvelancheAvelanche 1513 silver badges11 bronze badges 8
  • 1 If a es before b, return -1, if b es before a, return 1, otherwise check additional cases (HINT: if/else if/else is a clear pattern to follow for this). – crashmstr Commented Aug 19, 2021 at 11:21
  • Have you tried writing your custom sort logic when sorting your array? What did you try and what didn't work? – David Commented Aug 19, 2021 at 11:23
  • 1 Hint 2: if order is undefined, it es before an order that is not undefined. – crashmstr Commented Aug 19, 2021 at 11:29
  • I wrote a logic to sort using order but for objects where order is missing it is adding them in the end. function pare_order(a, b) { // a should e before b in the sorted order if (a.order < b.order) { return -1; // a should e after b in the sorted order } else if (a.order > b.order) { return 1; // a and b are the same } else { return 0; } } – Avelanche Commented Aug 19, 2021 at 11:30
  • If you don't care about performance too much, just create two arrays one without order (arr1) property and one with items having order (arr2) property. Push the items of arr1 to finalArr, then sort the items in arr2 and push it to finalArr. – Utkarsh Dixit Commented Aug 19, 2021 at 11:36
 |  Show 3 more ments

4 Answers 4

Reset to default 5

Logic is basic array sorting logic.

  • If both a.order and b.order are defined return 1 or -1 depending on the largest value.
  • If either one of them is undefined return 1 or -1 depending on the defined value.
  • Please Note: The value 1 and -1 determines the relative position between the two nodes. Returning 1 places a after b and -1 places a before b.

const testWidgetOrderSort = [
  { "_id": "name", "order": 1 },
  { "_id": "is", "order": 2 },
  { "_id": "my", "order": 0 },
  { "_id": "oh I would be very first" },
  { "_id": "adam", "order": 3 }
];
const output = testWidgetOrderSort.sort((a, b) => {
  if( a.order !== undefined && b.order !== undefined ) {
    return a.order > b.order ? 1 : -1;
  } else {
    return a.order !== undefined ? 1 : -1
  }
});
console.log(output);

I came up with something like this:

const test = [
  { "_id": "name", "order": 1 },
  { "_id": "is", "order": 2 },
  { "_id": "my", "order": 0 },
  { "_id": "oh I would be very first" },
  { "_id": "adam", "order": 3 }
];

const x = test.sort((a, b) => {
  const [STAY, SWAP] = [-1, 1];
  if (!a.hasOwnProperty('order')) { return STAY; }
  if (!b.hasOwnProperty('order')) { return SWAP; }
  return a.order - b.order;
});

console.log(x);

You just have to pass the custom parator function

if (!("order" in a)) return -1;
if (!("order" in b)) return 1;
else return a.order - b.order;

1) return -1 if property order doesn't exist in a.

2) return 1 if property order doesn't exist in b.

3) if both the object has order property then just sort in ascending order.

const arr = [
  { _id: "name", order: 1 },
  { _id: "is", order: 2 },
  { _id: "my", order: 0 },
  { _id: "oh I would be very first" },
  { _id: "adam", order: 3 },
];

const result = arr.sort((a, b) => {
  if (!("order" in a)) return -1;
  if (!("order" in b)) return 1;
  else return a.order - b.order;
});

console.log(result);

If you don't care about the performance too much, the below should be fine,

const testWidgetOrderSort = [
  { "_id": "name", "order": 1 },
  { "_id": "is", "order": 2 },
  { "_id": "my", "order": 0 },
  { "_id": "oh I would be very first" },
  { "_id": "adam", "order": 3 }

];

const finalArr = testWidgetOrderSort.filter(a => typeof a.order === "undefined");

const sortedArrWithOrderItems = testWidgetOrderSort.filter(a => typeof a.order !== "undefined").sort((a,b) => (a.order > b.order ? 1 : -1));

finalArr.push(...sortedArrWithOrderItems);

console.log(finalArr);

Note: Personally I would remend going with @Nitheesh or @decpk solution, it is more clean and performance wise better. My solution is just to give another solution for the problem

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论