JavaScript array.sort with multiple values (strings and numbers)
I would like to sort the array subject (string, alphabetically), then level (int, ascending), then name (string, alphabetically). I've found many other threads on SO, but I haven't found any of the multiple variable types. I thought I had it, but it doesn't sort correctly.
Sort function:
scipads.sort(function (a, b) {
if (a.subject != b.subject)
return a.subject < b.subject;
if (a.level != b.level)
return a.level - b.level;
return a.name < b.name;
});
Array:
var scipads = [{
"name": "L2 Physics Externals",
"level": 2,
"subject": "physics",
}, {
"name": "L2 Physics Internals",
"level": 2,
"subject": "physics",
}, {
"name": "L2 Chem Externals",
"level": 2,
"subject": "chemistry",
}, {
"name": "L2 Chem Internals",
"level": 2,
"subject": "chemistry",
}, {
"name": "L2 Bio Internals",
"level": 2,
"subject": "biology",
}, {
"name": "L2 Bio Externals",
"level": 2,
"subject": "biology",
}, {
"name": "L1 Electricity & Magnetism",
"level": 1,
"subject": "physics",
}, {
"name": "L1 Wave Behaviour",
"level": 1,
"subject": "physics",
}, {
"name": "L1 Heat",
"level": 1,
"subject": "physics",
}, {
"name": "L1 Carbon Chemistry",
"level": 1,
"subject": "chemistry",
}, {
"name": "L1 Selected Elements",
"level": 1,
"subject": "chemistry",
}, {
"name": "L1 Chemical Reactions",
"level": 1,
"subject": "chemistry",
},
];
How can I sort by topic, then level, and then name?
+3
source to share
5 answers
Use localeCompare
to compare strings
var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];
scipads.sort(function(a, b) {
if (a.subject != b.subject)
return a.subject.localeCompare(b.subject);
else if (a.level != b.level)
return a.level - b.level;
return a.name.localeCompare(b.name);
});
console.log(scipads);
+1
source to share
The comparison should return an integer . Here's an example:
scipads.sort((a, b) => {
if (a.subject != b.subject) {
return a.subject < b.subject ? -1 : 1;
}
if (a.level != b.level) {
return a.level - b.level;
}
return a.name < b.name ? -1 : 1;
})
+2
source to share
My solution, compare the topic first, then compare the level
var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];
// sort by subject, then level, then name
var res = scipads.sort((a, b) => {
if (a.subject > b.subject) {
return 1;
} else if (a.subject < b.subject) {
return -1;
} else if ( a.level > b.level){
return 1;
} else if (a.level < b.level) {
return -1;
} else if (a.name > b.name) {
return 1;
} else if (a.name < b.name) {
return -1;
}
return 0;
});
console.log(res)
0
source to share
To compare a string, you must use string.localeCompare
. Alternatively, you can try to create an array with a priority list and iterate over it to sort.
var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];
var priority = ["subject", "level", "name"]
scipads.sort(function(a,b){
var val = 0;
priority.some(function(k){
val = compare(a,b,k);
return val !== 0;
});
})
function compare(a,b,k){
switch(typeof a[k]){
case "string": return a[k].localeCompare(b[k]);
case "number": return a[k] - b[k]
}
}
console.log(scipads)
0
source to share