Lidt matematik:
At sortere en liste hurtigst gøres ved at tage den elementvist fra en ende af og bytte elementet ud med et tilfældigt. Det har en WCE (Worst Case Execution" på O(n) - altså direkte proportionelt med n (antal elementer)... Denne tilgang bruger gotchas eksempel som også er den hurtigste... Jeg tror måske nok, at jeg kunne optimere en lille smule, men ikke meget... Og dog... Hurtigere endnu er:
Array.prototype.shuffle = function() {
var l = this.length;
for (i in this) {
var r = random(l);
var t = this[i];
this[i] = this[r];
this[r] = t;
}
}
Den kører hurtigere, da den for det første bruger kortere navne (minimalt men eksisterende performance-gain) og derudover bruger for-in-strukturen... Denne er utrolig hurtig til at gennemløbe et array, hvis man blot skal løbe alle elementer igennem på et eller anden tidspunkt. Den tager nemlig ikke nødvendigvis elementerne i rækkefølge, men det er jo også ligemeget... Helt teknisk, så er for-in-løkken den eneste løkke, der benytter sig af stack-registrene i Flash-fortolkeren... Det kan man selvfølgelig manipulere sin for-løkke til vis assembler-kode... Læs meget mere om dette på
http://flash.sourceforge.netMht. diktators løsning, så udnytter hans løsning nogle helt andre aspekter af flash, nemlig den indbyggede sorteringsalgoritme, der kan tage en sorteringsfunktion...
Ideen i dette er, hvis man nu har nogle andre elementer i sig array end blot tal eller strenge, men måske objekter, så kan man stadig sortere - fx:
mitArray = new Array();
mitArray[0] = {fornavn:"Morten", efternavn:"Barklund"};
mitArray[1] = {fornavn:"Lars", efternavn:"Holmgård"};
mitArray[2] = {fornavn:"Michael", efternavn:"Diktator"};
mitArray[3] = {fornavn:"Hans", efternavn:"Jensen"};
Dette kan jo ikke sorteres ved hjælp af de almindelige <, > eller ==. Så kan man lave sin egen sorteringsfunktion:
function sorterFornavn(a,b) { //to tilfældige elementer
if (a.fornavn < b.fornavn) {
return -1;
} else if (a.fornavn > b.fornavn) {
return 1;
} else {
return 0;
}
}
For man skal nemlig returnere -1, hvis a kommer før b, 0 hvis de er ens og 1 hvis a kommer efter b... Sorter efter efternavn er selvfølgelig bare:
function sorterEfternavn(a,b) {
if (a.efternavn < b.efternavn) {
return -1;
} else if (a.efternavn > b.efternavn) {
return 1;
} else {
return 0;
}
}
Disse kaldes så med:
mitArray.sort(sorterFornavn);
mitArray.sort(sorterEfternavn);
Læs mere på
http://www.macromedia.com/support/flash/action_scripts/objects/arraysort.htmlFlash's sorteringsalgoritme er en sløv slavealgoritme (ikke rekursiv - tror nok den hedder "sort by insertion"/"insertion sort") der løber O(n*n) - altså proportionel med kvadratet på n = sløvt!
En god sorteringsalgoritme som quicksort løber O(n*log n). Flash-implementeringerne af denne kan findes rundt omkring...
Men hvorfor virker diktators eksempel så, som en shuffle, når den bruger sort()? Det skyldes blot, at hver gang sort() kalder din sorteringsfunktion, så får den tilfældigt enten -1, 0 eller 1, så den placerer elementer tilfældigt i forhold til hinanden...
Håber det gav indsigt...
/Barklund