Reputation: 13949
Assume I have an array of options to sort by multiple scores, and those scores are an array of variable length
[
#[Label, scores]
["Label6", [1]
["Label5", [1,5]
["Label2", [0,1,3,5],
["Label1", [0,1,2]
["Label3", [0,1,4],
["Label4", [1,4]
]
I want to sort this list by evaluating array elements one by one. IE. I will first sort (ascending) by the score[0]
, then score[i+1]
if it exists, etc. When score[i]
does not exist, it should be considered as an infinite value (appear at the bottom)
This could gives the following output on the previous data :
list = [
#[Label, scores]
["Label1", [0,1,2]
["Label2", [0,1,3,5],
["Label3", [0,1,4],
["Label4", [1,4]
["Label5", [1,5]
["Label6", [1]
]
How can I write this function ? Is there a native/ES6 (or lodash/underscore) sortBy()
function like we have in other languages ? (for example in Ruby you would simply list.sort_by(&:last)
to get this effect). Or does it need to be implemented manually ?
Upvotes: 2
Views: 228
Reputation: 386654
You could take the arrays, and sort by same index values.
At start take the minimum length of both arrays as the length for iterating the values and to prevent to take undefined
.
If the delta of two values of same index is not zero, return the delta, otherwise proceed with the next index.
If all indices are visited without a former return, all value at the same index are equal until the minimum length of both arrays. In this case return the delta of the length of both in switched order, because the longer array should come first.
var array = [["Label6", [1, 5]], ["Label2", [0, 1, 3, 5]], ["Label1", [0, 1, 2]], ["Label3", [0, 1, 4]], ["Label5", [1, 5, 2]], ["Label4", [1, 4]]];
array.sort(([, a], [, b]) => {
var delta,
index = 0,
length = Math.min(a.length, b.length);
while (index < length) {
delta = a[index] - b[index];
if (delta) return delta;
index++;
}
return b.length - a.length;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 1721
There is the array.sort()
function, which takes in a sorting algorithm and sorts the array for you based on that. all you have to do is implement the sorting for only 2 arguments.
here is what i'd do in your case:
list.sort( list1, list2 => {
let i = 0, iterations = min(list1.length, list2.length);
for( i = 0; i<iterations; i++ ){
if( list1[i] < list2[i] ) return -1;
if( list1[i] > list2[i] ) return 1;
}
if( list1.length === list2.length ) return 0;
if( i === list1.length ) return -1;
if( i === list2.length ) return 1;
}
Upvotes: 0