JSFiddle - React, Tailwind, and code Playground
by Mottie
HTML
<select>
<option value="a">a</option>
<option value="c">c</option>
<option value="a">a</option>
<option value="a">a</option>
<option value="f">f</option>
<option value="c">c</option>
<option value="c">c</option>
<option value="a">a</option>
<option value="f">f</option>
<option value="e">e</option>
<option value="a">a</option>
<option value="d">d</option>
<option value="b">b</option>
</select>
CSS
/*
- Option a: 5 times
- Option c: 3 times
- Option f: 2 times
Then we would like the select to be ordered a, c, f, b, d, e
*/
JavaScript
var indx,
xref = {},
newHtml = '',
$select = $('select'),
opts = $select.find('option')
// build array of options & count repeats
.map(function () {
var v = this.value;
if (xref[v]) {
xref[v]++
} else {
xref[v] = 1;
}
return v;
})
// sort options by adding "0" or "1" in front
// to perform a weighted sort so duplicates get sorted first
.sort(function(a, b){
var x = xref[a] > 1 ? '0' + a : '1' + a,
y = xref[b] > 1 ? '0' + b : '1' + b;
return x === y ? 0 : x > y ? 1 : -1;
}),
// return unique array values
arr = $.grep(opts, function (v, k) {
return $.inArray(v, opts) === k;
});
// replace current options with new list
for (indx = 0; indx < arr.length; indx++) {
newHtml += '<option value="' + arr[indx] + '">' + arr[indx] + '</option>';
}
$select.html(newHtml);