Reputation: 15685
I have an html list
<select>
<option value="w" count="1">w (1)</option>
<option value="a" count="1">a (1)</option>
<option value="d" count="5">d (5)</option>
<option value="r" count="0">r (0)</option>
<option value="q" count="0">q (0)</option>
<option value="s" count="0">s (0)</option>
<option value="b" count="5">b (5)</option>
</select>
I want the list to be order by count
first, then by value
.
Output:
<select>
<option value="b" count="5">b (5)</option>
<option value="d" count="5">d (5)</option>
<option value="a" count="1">a (1)</option>
<option value="w" count="1">w (1)</option>
<option value="q" count="0">q (0)</option>
<option value="r" count="0">r (0)</option>
<option value="s" count="0">s (0)</option>
</select>
I know how to sort by count
OR by value
but I don't find an easy way to combine them.
Sort by count:
select.sort(function (a, b) {
var c1 = parseInt($(a).attr('count'), 10);
var c2 = parseInt($(b).attr('count'), 10);
return c1 < c2 ? 1 : c1 > c2 ? -1 : 0;
});
and by value
select.sort(function (a, b) {
return $(a).text().toUpperCase().localeCompare($(b).text());
});
I am thinking about building an object:
var map = {
5: ['d', 'b'],
1: ['a', 'w'],
0: ['r', 'q', 's']
};
Then sort each keys:
function keys(map) {
var keys = [];
for (var key in map) {
if (map.hasOwnProperty(key)) map[key].sort();
}
return keys;
}
keys(map);
map;
And finally reconstruct the select
list.
Is there an easier way?
Upvotes: 0
Views: 163
Reputation: 72957
Try this:
select.sort(function (a, b) {
var c1 = parseInt($(a).attr('count'), 10);
var c2 = parseInt($(b).attr('count'), 10);
if(c1 === c2){ // If the counts are equal, return the comparison for value.
return $(a).text().toUpperCase().localeCompare($(b).text());
}
// Otherwise, compare the counts.
// (With numbers, you can just substract `b` from `a` in sort functions.)
return c1 - c2;
});
With the comments removed, that's just 6 lines of code.
There's no need to wrap the second return
in a else
, because the sort function won't ever evaluate an else
, if c1 === c2
, since the if
contains a return
statement.
Now, the sort
function expects X<0, X=0 or X>0
to be returned (Where X
is the output), depending on if a
is less than, equal to, or greater than b
. If you subtract b
from a
, you get the values you need.
Upvotes: 1
Reputation: 74086
Why not just combine both functions into one like this:
select.sort(function (a, b) {
var c1 = parseInt($(a).attr('count'), 10);
var c2 = parseInt($(b).attr('count'), 10);
if ( c1 == c2 ) {
return $(a).text().toUpperCase().localeCompare($(b).text());
} else {
return c1 < c2 ? 1 : -1;
}
});
Upvotes: 1