Mam nadzieję, że szybsza dwukierunkowa indexOf
/ lastIndexOf
alternatywna
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 contains
funkcję 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ę while
się 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 contains
funkcję, aby odzwierciedlić dane wyjściowe indexOf i lastIndexOf (tak w zasadzie true
za pomocą index
i za false
pomocą -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 while
wariant:
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