Home > Net >  Sort a key with optional object
Sort a key with optional object

Time:07-28

I have the following data as Input and I am trying to get the desired output as a result of sorting the data:

Input

[
    {
        "info": { "name": "abc" }
    },
    {
        "info": { "name": "def" }
    },
    {
        "info": {},
        "stats": { "packages": 10, "score": 10 }
    },
    {
        "info": {},
        "stats": { "packages": 5, "score": 8 }
    },
    {
        "info": {},
        "stats": { "packages": 7, "score": 6 }
    }
]

Desired Output - Sort by packages descending, if present

[
    {
        "info": {},
        "stats": { "packages": 10, "score": 10 }
    },
    {
        "info": {},
        "stats": { "packages": 7, "score": 6 }
    },
    {
        "info": {},
        "stats": { "packages": 5, "score": 8 }
    },
    {
        "info": { "name": "abc" }
    },
    {
        "info": { "name": "def" }
    }
]

So far I have this code to filter data that has stats object, apply sort on it and then combine it with data that does not stats object. I am wondering if there's an efficient way to do this.

filterData = [];
sortedData = [];
filterData = [...filterData, ...data.filter(x => x.stats)];
filterData.sort((a, b) => b.stats.packages.localeCompare(a.stats.packages));
sortedData = [...filterData, ...data.filter(x => !x.stats)];

CodePudding user response:

You need to define a custom sort function. A sort function takes in two arguments (elements from the array) and returns either a positive, negative, or zero value, depending on which element is considered bigger. Read about it more here: Array.prototype.sort().

Next up, to see if the package variable exists you can use Optional_chaining

const arr = [
    {
        "info": { "name": "abc" }
    },
    {
        "info": { "name": "def" }
    },
    {
        "info": {},
        "stats": { "packages": 10, "score": 10 }
    },
    {
        "info": {},
        "stats": { "packages": 5, "score": 8 }
    },
    {
        "info": {},
        "stats": { "packages": 7, "score": 6 }
    }
]

const sorted = arr.sort((item1, item2) => 
    (item2?.stats?.packages || 0) - (item1?.stats?.packages || 0)
)
console.log(sorted)

CodePudding user response:

If you do not have hundreds of data it should be efficient enough. Alternatively, you can use or write sort function like that:

data.sort((a, b) => (b.stats?.packages ?? 0) - (a.stats?.packages ?? 0))

CodePudding user response:

Using Array#sort, optinal-chaining, and nullish-operator:

const data = [
  { "info": { "name": "abc" } },
  { "info": { "name": "def" } },
  { "info": {}, "stats": { "packages": 10, "score": 10 } },
  { "info": {}, "stats": { "packages": 5, "score": 8 } },
  { "info": {}, "stats": { "packages": 7, "score": 6 } }
];

const sorted = data.sort((a, b) =>
  (b?.stats?.packages ?? 0) - (a?.stats?.packages ?? 0)
);

console.log(sorted);

CodePudding user response:

data = [
    {
        "info": { "name": "abc" }
    },
    {
        "info": { "name": "def" }
    },
    {
        "info": {},
        "stats": { "packages": 10, "score": 10 }
    },
    {
        "info": {},
        "stats": { "packages": 5, "score": 8 }
    },
    {
        "info": {},
        "stats": { "packages": 7, "score": 6 }
    }
]
const sorter = (a,b)=>{
  let aa = a.stats?a.stats.packages:1;
  let bb = b.stats?b.stats.packages:1;
  return bb - aa;
}
data.sort(sorter);
console.log(data)

hum .. like this ?

  • Related