昨天看了drop方法,今天是dropWhile方法。

使用

_.dropWhile(array, [predicate=_.identity])

创建一个切片数组,去除array中从起点开始到 predicate 返回假值结束部分。predicate 会传入3个参数: (value, index, array)。

value为数组的一个ele,index为当前数组的index,value为原数组。

 * var users = [
 *   { 'user': 'barney',  'active': false },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': true }
 * ];
 *
 * _.dropWhile(users, function(o) { return !o.active; });
 * // => objects for ['pebbles']
 *

其实看到这我有点懵逼,不知道是开了一天会的原因么。还是先翻源码吧。

function dropWhile(array, predicate) {
  return (array && array.length)
    ? baseWhile(array, baseIteratee(predicate, 3), true)
    : [];
}

dropWhile返回了baseWhile,看楼下的代码段,baseWhile返回了一个baseSlice。与drop相比,提供了一个predicate用于遍历迭代的函数,多使用到了一个baseWhile。类似于var dropWhile = (...) => baseWhile(...) => baseSlice(...)

function baseWhile(array, predicate, isDrop, fromRight) {
  var length = array.length,
      index = fromRight ? length : -1;

  while ((fromRight ? index-- : ++index < length) &&
    predicate(array[index], index, array)) {}

  return isDrop
    ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
    : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
}

predicate这个参数在传入baseWhile时,先被baseIteratee调用,我们先确认这个函数是用来做什么的。了解作者的目的。

import baseMatches from './_baseMatches.js';
import baseMatchesProperty from './_baseMatchesProperty.js';
import identity from './identity.js';
import isArray from './isArray.js';
import property from './property.js';

/**
 * The base implementation of `_.iteratee`.

 */
function baseIteratee(value) {
  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  if (typeof value == 'function') {
    return value;
  }
  if (value == null) {
    return identity;
  }
  if (typeof value == 'object') {
    return isArray(value)
      ? baseMatchesProperty(value[0], value[1])
      : baseMatches(value);
  }
  return property(value);
}

baseIteratee这个方法留给下一篇解决。暂时只讨论predicate为函数的情况。 baseIteratee会直接返回当前的传入的predicate.
baseWhile(array, baseIteratee(predicate, 3), true) => baseWhile(array, predicate, true)

我们再继续说baseWhilebaseWhile(array, predicate, isDrop, fromRight),从命名上来看,isDrop表示是否是drop方法,翻看其它部分,再takeWhile中也用到了baseWhilefromRight表示顺序是从右到左还是从左到右

假设我们当前fromRight为flase

我们思考如下代码,

 // now fromRight = false ,所有我们修改下代码
 var length = array.length,
      index =  -1;

  while ((++index < length) &&
    predicate(array[index], index, array)) {}

while循环如果符合条件会一直执行下去。当前while执行条件(++index < length) &&predicate(array[index], index, array),也就是遍历当前数组,然后当前数组对应的array[i]等参数传入predicate,一旦predicate返回fasle,就跳出当前循环,执行baseSlice

baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
//简化
baseSlice(array,  index,  length)// length为数组长度,index为不符合条件的角标。

predicate到底是什么

英文中是断言,断定的意思,我理解为一种判定(这里我有些模凌两可,感觉自己不对,有朋友纠正一下么。)

predicate函数用来判定符合你预先设定的条件,它总是返回true or false.如果不符合条件,说的直接点就是返回false,在baseWhile中就返回当前的index,然后去baseSlice(array,index,end)

关于baseSlice 上一篇我已经简单介绍过了。链接

这是我自己的乱言乱语,也希望对看到的人有帮助。


最普通的一个
301 声望41 粉丝

永远不要做你擅长的事。