Předpokládejme, že mám pole Javascript, například:
var test = ['b', 'c', 'd', 'a'];
Chci třídit pole. Je zřejmé, že to mohu udělat jen pro seřazení pole:
test.sort(); //Now test is ['a', 'b', 'c', 'd']
Ale to, co opravdu chci, je pole indexů, které udávají polohu seřazených prvků vzhledem k původním prvkům. Nejsem si úplně jistý, jak to formulovat, takže možná proto mám problém přijít na to, jak to udělat.
Pokud by se taková metoda jmenovala sortIndices(), pak bych chtěl:
var indices = test.sortIndices(); //At this point, I want indices to be [3, 0, 1, 2].
„a“ bylo na pozici 3, „b“ bylo na 0, „c“ bylo na 1 a „d“ bylo 2 v původním poli. Proto [3, 0, 1, 2].
Jedním z řešení by bylo seřadit kopii pole a poté procházet setříděné pole a najít pozici každého prvku v původním poli. Ale, to mi přijde neohrabané.
Existuje nějaká existující metoda, která dělá to, co chci? Pokud ne, jak byste postupovali při psaní metody, která to dělá?
Odpověď
var test = ['b', 'c', 'd', 'a']; var test_with_index = []; for (var i in test) { test_with_index.push([test[i], i]); } test_with_index.sort(function(left, right) { return left[0] < right[0] ? -1 : 1; }); var indexes = []; test = []; for (var j in test_with_index) { test.push(test_with_index[j][0]); indexes.push(test_with_index[j][1]); }
Upravit
Máte pravdu ohledně for .. in
. To se zlomí, pokud někdo zničí prototyp pole, což pozoruji nepříjemně často. Tady je to s tím opraveným a zabaleným do použitelnější funkce.
function sortWithIndeces(toSort) { for (var i = 0; i < toSort.length; i++) { toSort[i] = [toSort[i], i]; } toSort.sort(function(left, right) { return left[0] < right[0] ? -1 : 1; }); toSort.sortIndices = []; for (var j = 0; j < toSort.length; j++) { toSort.sortIndices.push(toSort[j][1]); toSort[j] = toSort[j][0]; } return toSort; } var test = ['b', 'c', 'd', 'a']; sortWithIndeces(test); alert(test.sortIndices.join(","));