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>