Надеемся, что более быстрый двунаправленный indexOf
/ lastIndexOf
альтернатива
2015
В то время как новый метод включает очень хорош, поддержка в настоящее время в основном равна нулю.
Давно я думал о том, как заменить медленные функции indexOf / lastIndexOf.
Эффективный путь уже найден, глядя на топовые ответы. Я выбрал функцию contains
от @Damir Zekic, которая должна быть самой быстрой. Но в нем также говорится, что контрольные показатели взяты с 2008 года и поэтому устарели.
Я также предпочитаю while
вместо for
, но по непонятной причине я закончил написание функции с помощью цикла for. Это также можно сделать с помощью while --
.
Мне было бы любопытно, если итерация была бы намного медленнее, если я проверяю обе стороны массива, делая это. По-видимому, нет, и поэтому эта функция примерно в два раза быстрее, чем те, которые проголосовали сверху. Очевидно, что это также быстрее, чем родной. Это в реальной среде, где вы никогда не узнаете, находится ли искомое значение в начале или в конце массива.
Когда вы знаете, что вы только что выдвинули массив со значением, использование lastIndexOf остается, вероятно, лучшим решением, но если вам нужно перемещаться по большим массивам, и результат может быть везде, это может быть надежным решением для ускорения работы.
Двунаправленный индексOf / 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
В качестве теста я создал массив с 100 тыс. Записей.
Три запроса: в начале, в середине и в конце массива.
Надеюсь, вы тоже найдете это интересным и протестируете производительность.
Примечание: Как вы можете видеть, я немного изменил функцию 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