Reputation: 5088
I have a variable and array of objects e.g:
var selectedName = 'fff';
[{
percentage: Math.round(percentage),
count: count,
name: 'bbb',
index: 11,
},
{
percentage: Math.round(percentage),
count: 200,
name: 'aaa',
index: 2,
},
{
percentage: Math.round(percentage),
count: 400,
name: 'All',
index: 7,
},
{
percentage: Math.round(percentage),
count: count,
name: 'fff',
index: 8,
},
{
percentage: Math.round(percentage),
count: count,
name: 'ccc',
index: 3,
}],
I want to sort these as follows: the object which has the name 'All' should always be first. The next object should be the one with the name that matches selectedName
, in this case 'fff'. And then the rest of the objects should be ordered by ascending order of their 'index' property.
Is this possible in one Array.sort() method?
Upvotes: 1
Views: 93
Reputation: 41893
You can use a helping object holding the priority of each element. In your particular case, the highest priority has All
value.
So firstly we sort the values with higher priority (All, 'fff')
and when it's done, we sort the rest by the index
value.
Note: Since we are sorting it by ascending order the priority values have to be negative. If we would sort it by a descending order (b - a)
, they would be positive.
var arr = [{percentage:Math.round("percentage"),count:"count",name:"bbb",index:11},{percentage:Math.round("percentage"),count:200,name:"aaa",index:2},{percentage:Math.round("percentage"),count:400,name:"All",index:7},{percentage:Math.round("percentage"),count:"count",name:"fff",index:8},{percentage:Math.round("percentage"),count:"count",name:"ccc",index:3}],
selectedName = 'fff',
result = arr.sort(function(a,b){
var order = {All: -2, [selectedName]: -1, default: 0};
return (order[a.name] || order.default) - (order[b.name] || order.default) || a.index - b.index;
});
console.log(result);
Upvotes: 1
Reputation: 24925
You can try something like this:
(a.name !== priorityName)
will yield a boolean value. When you use -
(minus) operator on them, it is converted to numeric value(true: 1, false: 0).1
and output will be 0
, which is falsey in JS.var selectedName = 'fff';
var priorityName = "All";
var percentage = 50.4, count= 0;
var data=[{percentage:Math.round(percentage),count:count,name:"bbb",index:11},{percentage:Math.round(percentage),count:200,name:"aaa",index:2},{percentage:Math.round(percentage),count:400,name:"All",index:7},{percentage:Math.round(percentage),count:count,name:"fff",index:8},{percentage:Math.round(percentage),count:count,name:"ccc",index:3}];
data.sort(function(a,b){
return (a.name !== priorityName) - (b.name !== priorityName) ||
(a.name !== selectedName) - (b.name !== selectedName) ||
a.index - b.index;
})
console.log(data)
Upvotes: 1
Reputation: 115498
Sure you can do it like so:
var selectedName = 'fff';
var percentage = 23;
var count = 3;
var data=[{percentage:Math.round(percentage),count:count,name:"bbb",index:11},{percentage:Math.round(percentage),count:200,name:"aaa",index:2},{percentage:Math.round(percentage),count:400,name:"All",index:7},{percentage:Math.round(percentage),count:count,name:"fff",index:8},{percentage:Math.round(percentage),count:count,name:"ccc",index:3}];
function sortItems(a, b) {
if (a.name === 'All') {
return -1
}
if (b.name === 'All') {
return 1;
}
if (a.name === selectedName) {
return -1
}
if (b.name === selectedName) {
return 1
}
return a.index - b.index;
}
console.log(items.sort(sortItems));
Upvotes: 1
Reputation: 7360
Yes, here an example:
var selectedName = 'fff';
let percentage = 1;
let count = 2;
var data=[{percentage:Math.round(percentage),count:count,name:"bbb",index:11},{percentage:Math.round(percentage),count:200,name:"aaa",index:2},{percentage:Math.round(percentage),count:400,name:"All",index:7},{percentage:Math.round(percentage),count:count,name:"fff",index:8},{percentage:Math.round(percentage),count:count,name:"ccc",index:3}];
arr.sort((i, j) => {
if (i.name === j.name && (i.name === 'All' || i.name === selectedName)) return 0;
if (i.name === 'All') return -1;
if (j.name === 'All') return 1;
if (i.name === selectedName) return -1;
if (j.name === selectedName) return 1;
if (i.index < j.index) return -1;
if (i.index > j.index) return 1;
return 0;
})
console.log(arr)
Upvotes: 4