arr.map(function(str, i){
return {
index: i,
length: str.length,
value: str
}
}).sort(function(a, b){
return b.length - a.length || a.index - b.index;
}).map(function(obj){
return obj.value;
})
This may seem like to much overhead, but as soon as you have to somehow compute the value you are sorting on, it's faster to compute it once and store it to some Object, than computing it potentially in a n*(n-1) operation.
So this approach in sorting is often the more performant one.
Or you generallize the two mapping-tasks:
var valueIndex = function(value,index){ return {value:value,index:index} };
var getValue = function(obj){ return obj.value };
arr.map(valueIndex)
.sort(function(a, b){
return b.value.length - a.value.length || a.index - b.index
})
.map(getValue);
ES6
var valueIndex = (value,index) => { return {value,index} };
var getValue = ({value}) => value;
arr.map(valueIndex)
.sort((a, b) => b.value.length - a.value.length || a.index - b.index)
.map(getValue);
sortis not stable, so you have to work around this by first creating a new arrayarr2of pairs(el, i)whereelis the element ofarrat positioni, then sort these pairs lexicographically, finally strip down the secondielement. Alternatively write your own custom stable sorting algorithm (e.g. merge sort).