Umarım daha hızlı çift yönlü indexOf
/ lastIndexOf
alternatif
2015
Yeni yöntem içeren çok güzel olsa da , destek şimdilik sıfırdır.
Uzun bir süre yavaş indexOf / lastIndexOf işlevlerini değiştirmenin yolunu düşünüyordum.
En iyi cevaplara bakıldığında zaten başarılı bir yol bulundu. Onlardan contains
@Damir Zekic tarafından gönderilen ve en hızlı olması gereken işlevi seçtim . Ama aynı zamanda kriterlerin 2008'den beri olduğunu ve bu yüzden modası geçmiş olduğunu belirtiyor.
Ben de tercih while
üzerinde for
değil, belirli bir nedenle ben bir for döngüsü ile işlev yazma sona erdi. Ayrıca a ile de yapılabilir while --
.
Bunu yaparken dizinin her iki tarafını da kontrol edersem yinelemenin çok daha yavaş olup olmadığını merak ettim. Görünüşe göre hayır, bu yüzden bu işlev en çok oy alanlardan iki kat daha hızlı. Tabii ki yerli olandan da daha hızlı. Bu, aradığınız değerin dizinin başında mı yoksa sonunda mı olduğunu asla bilemeyeceğiniz gerçek bir dünya ortamında.
Sadece bir değere sahip bir dizi ittiğinizi bildiğinizde, lastIndexOf'u kullanmak muhtemelen en iyi çözüm olmaya devam eder, ancak büyük dizilerden geçmeniz gerekiyorsa ve sonuç her yerde olabilirse, işleri daha hızlı hale getirmek için sağlam bir çözüm olabilir.
Çift yönlü dizinOf / 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');
Performans testi
http://jsperf.com/bidirectionalindexof
Test olarak 100k girişli bir dizi oluşturdum.
Üç sorgu: başında, ortasında ve dizinin sonunda.
Umarım bunu ilginç bulursunuz ve performansı test edersiniz.
Not: Ben biraz değiştirilmiş görebileceğiniz gibi contains
(yani temelde indexOf & lastIndexOf çıkışını yansıtacak şekilde işlev true
ile index
ve false
ile -1
). Bu ona zarar vermemeli.
Dizi prototipi değişkeni
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');
İşlev, doğru ya da yanlış ya da nesne, dize ya da her neyse döndürmek için kolayca değiştirilebilir.
Ve işte while
varyant:
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');
Bu nasıl mümkün olabilir?
Bir dizide yansıyan indeksi elde etmek için basit hesaplama, gerçek bir döngü yineleme yapmaktan iki kat daha hızlı olduğunu düşünüyorum.
İşte yineleme başına üç kontrol yapan karmaşık bir örnek, ancak bu sadece kodun yavaşlamasına neden olan daha uzun bir hesaplama ile mümkündür.
http://jsperf.com/bidirectionalindexof/2