JavaScript 用一個一元函數精簡地實現 ES6 的 findIndex 與 findLastIndex 方法

普通地實現 findIndex 與 findLastIndex

ES6 新增了 findIndex 與 findLastIndex 數組方法,可以正序、反序地查詢,並返回數組中滿足回調函數的第一個元素的索引,否則返回 -1。

// 用法
arrayObj.findIndex(callbackfn [, thisArg]);
// 回調函數用法
function callbackfn(value, index, arrayObj)

實現 findIndex():

只需要遍歷元素,逐個判斷即可。

思路明確,代碼如下

代碼:

Array.prototype.fakeFindIndex = function (cb, context) {
  let array = this;

  for (let i = 0; i < array.length; i++) {
    const element = array[i];
    if (cb.call(context, element, i, array)) {
      return i
    }
  }
  return -1
}

簡單測試:

console.log([9, 9, 6].fakeFindIndex(item => (item === 6)))
// 輸出:2

實現 findLastIndex():

findLastIndex 與 前者的區別就在於它是逆序遍歷的。所以,只需要改變 for 循環遍歷順序就可以了。

代碼:

Array.prototype.fakeFindLastIndex = function (cb, context) {
  let array = this;

  for (let i = array.length-1; i >=0; i--) {
    const element = array[i];
    if (cb.call(context, element, i, array)) {
      return i
    }
  }
  return -1
}

簡單測試:

console.log([10, 10, 6].fakeFindLastIndex(item => (item === 6)))
// 輸出:2

用一個函數精簡地實現

上面兩個函數的區別很小,重複代碼很多。

underscore 用一個函數實現了它們,巧妙地用一個參數來控制遍歷順序:

當參數 dir:

  • 爲 1:得到正序遍歷方法;
  • 爲 -1: 得到逆序遍歷方法。

道理簡單而巧妙,上代碼:

代碼

function createIndexFinder(dir) {
  return function (array, cb, context) {
    let length = array.length;
    // 控制初始 index0 或者 length-1
    let index = dir >= 0 ? 0 : length - 1;

    // 條件: 在數組範圍內;
    // 遞增或遞減:遞加 1 或者 -1; 妙啊~
    for( ; index >= 0 && index <= length - 1; index += dir ) {
      if( cb.call(context, array[index], index) ) return index
    }
    return -1
  }
}

用例:

const findIndex = createIndexFinder(1);
const findLastIndex = createIndexFinder(-1);

【空城下的司馬懿臉:妙啊~】

參考:
https://github.com/mqyqingfeng/Blog/issues/37

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章