Reputation: 469
Alright, so I have an array of objects that includes null values for a certain property.
The object looks roughly like this for sorting purposes... (40 elements, but this will suffice...).
It needs to be sorted based on roulette
descending (with roulette
sometimes being null), then novelty
, then popularity
.
My head is getting a bit crushed.
This works to sort the roulette
in descending, but how do I need to extend it to include the other two criteria?
Object:
[
{
title: 'one',
popularity: 4,
novelty: 3
},
{
title: 'two',
popularity: 1
novelty: 4
},
{
title: 'three',
popularity: 5,
novelty: 3,
roulette: 0
},
{
title: 'four',
popularity: 5,
novelty: 3,
roulette: 1
}
]
Partially working function:
object.sort(function(a, b) {
if (a['roulette'] == null) return 1
if (b['roulette'] == null) return -1
if (a['roulette'] === b['roulette']) return 0
return b.roulette > a.roulette ? 1 : -1
});
Upvotes: 2
Views: 1950
Reputation: 42352
Here is the preferential sorting (descending) with roulette
, novelty
and popularity
(in that order)
This handles both null
and undefined
- check out the demo below:
var object=[{title:"one",popularity:4,novelty:3},{title:"two",popularity:1,novelty:4},{title:"three",popularity:5,novelty:3,roulette:0},{title:"four",popularity:5,novelty:3,roulette:1},{title:"five",roulette:4,novelty:null},{title:"six",popuplarity:7},{title:"seven",novelty:8,roulette:null},{title:"eight",novelty:0},{title:"nine",popularity:10}];
function ifNumber(num) {
if(num == undefined || num == null)
return -Infinity;
else
return num;
}
var result = object.sort(function(a, b) {
return (ifNumber(b.roulette) - ifNumber(a.roulette))
|| (ifNumber(b.novelty) - ifNumber(a.novelty))
|| (ifNumber(b.popuplarity) - ifNumber(a.popuplarity));
});
console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}
Upvotes: 1
Reputation: 386560
An attempt with sorting with priority and groups.
var data = [{ title: 'one', popularity: 4, novelty: 3 }, { title: 'two', popularity: 1, novelty: 4 }, { title: 'three', popularity: 5, novelty: 3, roulette: 0 }, { title: 'four', popularity: 5, novelty: 3, roulette: 1 }, { title: 'five', popularity: 5, novelty: 4, roulette: null }, { title: 'six', popularity: 5, novelty: 5, roulette: undefined }];
data.sort(function (a, b) {
return (
(a.roulette === undefined || a.roulette === null) - (b.roulette === undefined || b.roulette === null) ||
a.roulette - b.roulette ||
a.novelty - b.novelty ||
a.popularity - b.popularity
);
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3
Reputation: 2691
You just have to keep on breaking ties if one parameter is same.
obj.sort(function(a, b) {
var rouletteDiff = compare(a.roulette, b.roulette);
if(rouletteDiff != 0) return rouletteDiff;
var noveltyDiff = compare(a.novelty, b.novelty);
if(noveltyDiff != 0) return noveltyDiff;
return compare(a.popularity, b.popularity);
});
function compare(x,y){
if(x == undefined) return 1;
if(y == undefined) return -1;
if(x === y){
return 0;
}else{
return x > y ? -1 : 1
}
}
Upvotes: 0
Reputation: 288100
Just include more conditionals:
var data = [{"title":"one","popularity":4,"novelty":3},{"title":"two","popularity":1,"novelty":4},{"title":"three","popularity":5,"novelty":3,"roulette":0},{"title":"four","popularity":5,"novelty":3,"roulette":1}];
data.sort(function(a,b) {
if (a.roulette < b.roulette || a.roulette == null) return +1;
if (a.roulette > b.roulette || b.roulette == null) return -1;
if (a.novelty < b.novelty || a.novelty == null) return +1;
if (a.novelty > b.novelty || b.novelty == null) return -1;
if (a.popularity < b.popularity || a.popularity == null) return +1;
if (a.popularity > b.popularity || b.popularity == null) return -1;
return 0;
})
console.log(data);
Upvotes: 0
Reputation: 24915
You can try sorting based on weighted rank:
var data=[{title:"one",popularity:4,novelty:3},{title:"two",popularity:1,novelty:4},{title:"three",popularity:5,novelty:3,roulette:0},{title:"four",popularity:5,novelty:3,roulette:1}];
data.sort(function(a, b) {
var r1 = a.roulette === undefined ? -1 : a.roulette;
var r2 = b.roulette === undefined ? -1 : b.roulette;
var n1 = a.novelty === undefined ? -1 : a.novelty;
var n2 = b.novelty === undefined ? -1 : b.novelty;
var p1 = a.popularity === undefined ? -1 : a.popularity;
var p2 = b.popularity === undefined ? -1 : b.popularity;
var r_rank = r1 > r2 ? -100 : r1 < r2 ? 100 : 0;
var n_rank = n1 > n2 ? -10 : n1 < n2 ? 10 : 0;
var p_rank = p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
return r_rank + n_rank + p_rank;
})
var r_rank = r1 > r2 ? -100 : r1 < r2 ? 100 : 0;
var n_rank = n1 > n2 ? -10 : n1 < n2 ? 10 : 0;
var p_rank = p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
return r_rank + n_rank + p_rank;
})
console.log(data)
Upvotes: 0