Надеемся, более быстрый двунаправленный indexOf
/ lastIndexOf
альтернативный
2015
В то время как новый метод включает в себя очень хорошо, поддержка пока практически нулевая.
Давно я думал о том, как заменить медленные функции indexOf / lastIndexOf.
Эффективный путь уже найден, глядя на топовые ответы. Из них я выбрал contains
функцию @Damir Zekic, которая должна быть самой быстрой. Но в нем также говорится, что показатели взяты с 2008 года и поэтому устарели.
Я также предпочитаю while
более for
, но не по определенной причине я закончил писать эту функцию с для цикла. Это также может быть сделано с while --
.
Мне было любопытно, если итерация была бы намного медленнее, если я проверяю обе стороны массива, делая это. По-видимому, нет, и поэтому эта функция примерно в два раза быстрее, чем те, которые проголосовали сверху. Очевидно, что это также быстрее, чем родной. Это в реальной среде, где вы никогда не узнаете, находится ли искомое значение в начале или в конце массива.
Когда вы знаете, что вы только что выдвинули массив со значением, использование lastIndexOf остается, вероятно, лучшим решением, но если вам нужно перемещаться по большим массивам, и результат может быть везде, это может быть надежным решением для ускорения работы.
Двунаправленный 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');
Тест производительности
http://jsperf.com/bidirectionalindexof
В качестве теста я создал массив с 100k записей.
Три запроса: в начале, в середине и в конце массива.
Я надеюсь, что вы также найдете это интересным и протестируете производительность.
Примечание. Как вы можете видеть, я немного изменил contains
функцию, чтобы отразить выходные данные indexOf & lastIndexOf (так, в основном, true
с index
и false
с -1
). Это не должно причинить вреда.
Вариант прототипа массива
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');
Функцию также можно легко изменить, чтобы она возвращала истину или ложь или даже объект, строку или что-то еще.
И вот while
вариант:
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');
Как это возможно?
Я думаю, что простой расчет для получения отраженного индекса в массиве настолько прост, что он в два раза быстрее, чем выполнение реальной итерации цикла.
Вот сложный пример выполнения трех проверок за итерацию, но это возможно только при более длинных вычислениях, которые вызывают замедление кода.
http://jsperf.com/bidirectionalindexof/2