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

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