Mam nadzieję, że szybsza dwukierunkowa indexOf/ lastIndexOfalternatywna
2015 r
Podczas gdy nowa metoda obejmuje jest bardzo przyjemna, wsparcie jest w zasadzie zerowe na razie.
Już dawno myślałem o sposobie zastąpienia powolnych funkcji indexOf / lastIndexOf.
Znaleźliśmy już skuteczny sposób, patrząc na najlepsze odpowiedzi. Z tych wybrałem containsfunkcję opublikowaną przez @Damir Zekic, która powinna być najszybsza. Ale stwierdza również, że poziomy odniesienia pochodzą z 2008 r., A więc są nieaktualne.
Ja też wolę whilesię for, ale nie konkretnego powodu skończyło pisanie funkcji z pętli for. Można to również zrobić za pomocą while --.
Byłem ciekawy, czy iteracja jest znacznie wolniejsza, jeśli sprawdzę obie strony tablicy podczas jej wykonywania. Najwyraźniej nie, a więc ta funkcja jest około dwa razy szybsza niż te najczęściej wybierane. Oczywiście jest także szybszy niż rodzimy. To w prawdziwym świecie, w którym nigdy nie wiadomo, czy szukana wartość znajduje się na początku, czy na końcu tablicy.
Kiedy wiesz, że właśnie wypchnąłeś tablicę z wartością, użycie lastIndexOf pozostaje prawdopodobnie najlepszym rozwiązaniem, ale jeśli musisz podróżować przez duże tablice, a wynik może być wszędzie, może to być solidne rozwiązanie, aby przyspieszyć.
Dwukierunkowy indexOf / lastIndexOf
function bidirectionalIndexOf(a, b, c, d, e){
for(c=a.length,d=c*1; c--; ){
if(a[c]==b) return c; //or this[c]===b
if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
}
return -1
}
//Usage
bidirectionalIndexOf(array,'value');
Test wydajności
http://jsperf.com/bidirectionalindexof
Jako test stworzyłem tablicę zawierającą 100 000 wpisów.
Trzy zapytania: na początku, w środku i na końcu tablicy.
Mam nadzieję, że to również Cię zainteresuje i przetestujesz wydajność.
Uwaga: Jak widać nieznacznie zmodyfikowałem containsfunkcję, aby odzwierciedlić dane wyjściowe indexOf i lastIndexOf (tak w zasadzie trueza pomocą indexi za falsepomocą -1). To nie powinno tego zaszkodzić.
Wariant prototypowy tablicy
Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
for(c=this.length,d=c*1; c--; ){
if(this[c]==b) return c; //or this[c]===b
if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
}
return -1
},writable:false, enumerable:false});
// Usage
array.bidirectionalIndexOf('value');
Funkcję można również łatwo zmodyfikować, aby zwracała wartość prawda lub fałsz, a nawet obiekt, ciąg znaków lub cokolwiek to jest.
A oto whilewariant:
function bidirectionalIndexOf(a, b, c, d){
c=a.length; d=c-1;
while(c--){
if(b===a[c]) return c;
if(b===a[d-c]) return d-c;
}
return c
}
// Usage
bidirectionalIndexOf(array,'value');
Jak to jest możliwe?
Myślę, że proste obliczenia, aby uzyskać indeks odbity w tablicy, są tak proste, że są dwa razy szybsze niż wykonanie iteracji pętli.
Oto złożony przykład wykonywania trzech kontroli na iterację, ale jest to możliwe tylko przy dłuższych obliczeniach, które powodują spowolnienie kodu.
http://jsperf.com/bidirectionalindexof/2