underscore源码解析(10)--集合的查找和筛选(上)(Collection Functions)

该项目的 GitHub 地址为 underscore-analysis,所有文章都在这里,并将不断更新。如果你觉得我的解读还可以,对你学习 js 有一定的帮助,欢迎 Watch && Star,你的关注和肯定必定会促使我投入更多的时间和经历做好这个系列。如果你愿意的话,也欢迎 Fork,我们一起来将这个系列做好做大,一起成长。


在对象方法部分,我们已经解读过针对对象的查找和筛选了。这篇文章我们来介绍一下适用范围更广的查找和筛选方法。

_.find(obj, predicate, context)

示例:

var even = _.find([1, 2, 3, 4, 5, 6],
function(num){ return num % 2 == 0; });
// => 2

源码解读:

_.find = _.detect = function(obj, predicate, context) {
// 声明一个监听变量,用来保存数组的索引值或者对象的属性值
var key;
// 如果 obj 是一个数组或类数组
if (isArrayLike(obj)) {
// 返回数组或类数组中符合 predicate 条件的元素的索引值,保存到 key 中
key = _.findIndex(obj, predicate, context);
} else {
// 如果 obj 是对象,那么返回符合 predicate 条件的属性的属性名,保存到 key
key = _.findKey(obj, predicate, context);
}
// 如果 key 在对象、数组(类数组)中,那么就返回对应的值
if (key !== void 0 && key !== -1) return obj[key];
};

依赖:
在该方法中,主要执行逻辑由它依赖的两个方法完成:

  • 用于查找数组中符合条件的元素的索引的方法,_.findIndex()
  • 用于查找对象中符合条件的属性值的属性名的方法,_.findKey()

_.filter(list, predicate, context)

遍历 list 中的每一个值,将所有通过了 predicate 检测的值保存到一个数组中,最后将这个数组返回。
示例:

var even = _.filter([1, 2, 3, 4, 5, 6],
function(num){ return num % 2 == 0; });
// => [2, 4, 6]

源码解读:

_.filter = _.select = function(obj, predicate, context) {
// 声明一个空数组,用于保存符合 predicate 条件的集合元素
var results = [];
// 为 predicate 绑定 context 上下文
predicate = cb(predicate, context);
// 迭代集合中的每一个元素,并对其执行一次回调
_.each(obj, function(value, index, list) {
// 检查迭代中的元素是否能通过 predicate 的检测,
// 如果能则将元素值保存到 results 中
if (predicate(value, index, list)) results.push(value);
});
// 返回包含了所有通过检测元素的数组
return results;
};

依赖:

_.contains(list, item, fromIndex)

如果 item 是 list 的元素或者属性值,则返回 true。如果 list 是数组,可以用 fromIndex 指定从哪个位置开始查找。
示例:

_.contains([1, 2, 3], 2);
// => true
_.contains([1, 2, 3], 2, 2);
// => false
_.contains({name: "comma", age: 26, hobby: "Programing"}, "comma");
// => true

源码解读:

_.contains = _.includes = _.include = function(obj, item,
fromIndex, guard) {
// 如果 obj 是对象,那么就获取该对象的所有属性值
if (!isArrayLike(obj)) obj = _.values(obj);
// 如果没有指定 fromIndex ,那么就将 fromIndex 设置为 0
if (typeof fromIndex != "number" || guard) fromIndex = 0;
// 用 underscore 定义的 indexOf 来检测 item 在数组或对象属性值数组中的索引
return _.indexOf(obj, item, fromIndex) >= 0;
};

依赖: