Home > Net >  Sorting array of Objects whilst keeping a couple of Objects in the last positions
Sorting array of Objects whilst keeping a couple of Objects in the last positions

Time:11-05

I am having a little difficulty sorting an array of objects. At the moment I have a dataset like sorting

[
   {
      "index":"football",
      "values":0.3,
      "id":"1"
   },
    {
      "index":"Unknown",
      "values":0.5,
      "id":"2"
   },
   {
      "index":"golf",
      "values":0.1,
      "id":"3"
   },
   {
      "index":"cricket",
      "values":0.222,
      "id":"4",
   },
   {
      "index":"Other",
      "values":0.333,
      "id":"5"
   },
   {
      "index":"netball",
      "values":0.753,
      "id":"6",
   },
]

What I am trying to do is sort this based on their values, with the highest being on top. To do this, I done

myDataSet.sort((a, b) => parseFloat(b.values) - parseFloat(a.values));

This seems to work. However, it is the second part I am struggling with. Whatever order it sorts in I always need Other 2nd from bottom and Unknown bottom. So the above should turn into this

[
   {
      "index":"netball",
      "values":0.753,
      "id":"6",
   },
   {
      "index":"football",
      "values":0.3,
      "id":"1"
   },
   {
      "index":"cricket",
      "values":0.222,
      "id":"4",
   },
   {
      "index":"golf",
      "values":0.1,
      "id":"3"
   },
   {
      "index":"Other",
      "values":0.333,
      "id":"5"
   },
   {
      "index":"Unknown",
      "values":0.5,
      "id":"2"
   },
]

I tried using a filter, this seems to put them at the bottom but then the rest are no longer sorted

myDataSet.filter((e) => e.index === 'Other')
    .filter((e) => e.index === 'Unknown')
    .sort((a, b) => parseFloat(b.values) - parseFloat(a.values));

How can I sort based on their values but keep Other and Unknown at the bottom?

Thanks

CodePudding user response:

You could sort the array directly with an object for wanted order and a default value for all other unknown values.

Then use values directly without conversion.

const
    data = [{ index: "netball", values: 0.753, id: "6" }, { index: "football", values: 0.3, id: "1" }, { index: "cricket", values: 0.222, id: "4" }, { index: "golf", values: 0.1, id: "3" }, { index: "Other", values: 0.333, id: "5" }, { index: "Unknown", values: 0.5, id: "2" }],
    bottom = { Other: 1, Unknown: 2 };

data.sort((a, b) =>
    (bottom[a.index] || 0) - (bottom[b.index] || 0) ||
    b.values - a.values
);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I'd suggest creating a custom function to determine sort order, say getSortValue(), then using Array.sort():

let a = [ { "index":"football", "values":0.3, "id":"1" }, { "index":"Unknown", "values":0.5, "id":"2" }, { "index":"golf", "values":0.1, "id":"3" }, { "index":"cricket", "values":0.222, "id":"4", }, { "index":"Other", "values":0.333, "id":"5" }, { "index":"netball", "values":0.753, "id":"6", }, ] 

function getSortValue(obj) {
    const key = obj.index.toLowerCase();
    return { "unknown": -2, "other": -1 }[key] || obj.values;   
}

console.log(a.sort((a,b) => getSortValue(b) - getSortValue(a)));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related