博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Underscore求数组的交集、并集和差集
阅读量:6717 次
发布时间:2019-06-25

本文共 3133 字,大约阅读时间需要 10 分钟。

1 数组交集函数——intersection

数组的交集是指包含多个数组中的共同元素的一个数组,求数组的交集就是找出给定数组中的共有元素。

下面实现一个求两个数组交集的函数。

判断数组是够包含指定值,使用Array.indexOf就可以。所以我们可以遍历第一个参数数组,然后使用Array.indexOf方法检索第二个参数数组,如果第二个参数数组包含当前项,那么当前项即为两个数组的交集元素,放入结果数组即可:

var intersection = function(arr1, arr2) {    var length = arr1.length;    var result = [];    var i;    for(i = 0; i < length; i++) {        if(result.indexOf(arr1[i]) >= 0)             continue;        else {            if(arr2.indexOf(arr1[i]) >= 0)                result.push(arr1[i]);        }    }    return result;}复制代码

以上代码实现了求两个数组交集的功能。

如果涉及到多个数组呢?那就是Underscore的实现方法了。

以下是Underscore的源码(附注释):

// Produce an array that contains every item shared between all the// passed-in arrays.//获取传入的多个数组的交集,之所以只有一个形参,是因为该函数使用第一个数组参数作为基准。_.intersection = function (array) {	//将要返回的结果数组。	var result = [];	//传入数组的个数。	var argsLength = arguments.length;	//遍历第一个数组参数。	for (var i = 0, length = getLength(array); i < length; i++) {		//当前项。		var item = array[i];		//如果结果数组中已有该项,那么直接跳过当前循环,进入下一轮循环中。		if (_.contains(result, item)) continue;		var j;		//从第二个参数开始,遍历每一个参数。		for (j = 1; j < argsLength; j++) {			//一旦有一个参数数组不包含item,就退出循环。			if (!_.contains(arguments[j], item)) break;		}		//如果所有参数数组都包含item项,就把item放入result。		if (j === argsLength) result.push(item);	}	return result;};复制代码

可以看到该函数一次接受多个数组,但是只有一个形参(array),该参数表示接收到的第一个数组,Underscore使用它作为参考,遍历该数组,然后依次判断剩余参数数组是否包含当前项,如果全部包含则该项为交集元素,推入结果数组当中。

2 数组并集函数——union

数组的并集是指包含指定的多个数组的所有元素的数组,求多个数组的并集即为求一个包含所有数组的所有元素的数组。

这里最直接的实现方法就是遍历所有数组参数,然后针对数组的每一项,放入到结果数组中(如果已经存在于结果数组中那么久不再添加)。

var union = function() {	var arrays = arguments;	var length = arguments.length;	var result = [];	var i;	for(i = 0; i < length; i++) {		var arr = arrays[i];		var arrLength = arrays[i].length;		for(var j = 0; j < arrLength; j++) {			if(result.indexOf(arr[j]) < 0) {				result.push(arr[j]);			}		}	}	return result;}复制代码

在阅读Underscore源码的时候,感觉它的实现方法十分巧妙。

Underscore中已经有了很多工具方法,所以可以拿来直接使用,比如、、。为什么强调这几个方法呢?因为使用这几个方法就可以实现数组求并集。

我们的union方法是接受多个数组作为参数的,而restArgs可以把多个数组参数合并到一个数组中作为参数;然后通过flatten函数,我们可以把得到的这个数组参数展开,展开之后得到的数组就是包含所有数组参数的所有元素的一个数组了,但是这个数组中有冗余项,我们必须对其进行去重;这时候使用我们的uniq工具函数就可以对其进行去重了。

经过这三个函数的处理,我们得到的数组就是多个数组参数的并集!

Underscore源码:

// Produce an array that contains the union: each distinct element from all of// the passed-in arrays._.union = restArgs(function (arrays) {	return _.uniq(flatten(arrays, true, true));});复制代码

这样的实现是不是很简介大气?

3 数组差集函数——difference

数组的差集是指由数组A中所有不属于数组B的元素所组成的一个数组。

直接的实现方法就是遍历前者,然后判断每个元素是否属于后者,如果不属于,那么就推入结果数组。

简单实现:

var difference = function(arr1, arr2) {	var length = arr1.length;	var i;	var result = [];	for(i = 0; i < length; i++) {		if(arr2.indexOf(arr1[i]) < 0) {			result.push(arr1[i]);		}	}	return result;}复制代码

Underscore的实现(附注释):

// Take the difference between one array and a number of other arrays.// Only the elements present in just the first array will remain.//数组求差集函数。//通过restArgs函数把第二个数组开始的所有参数数组合并到一个数组。_.difference = restArgs(function (array, rest) {	//使用flatten展开rest数组。	rest = flatten(rest, true, true);	//使用filter函数过滤array数组达到求差集的目的,判断条件就是value是否属于rest。	return _.filter(array, function (value) {		return !_.contains(rest, value);	});});复制代码

更多Underscore源码解析:

转载地址:http://onumo.baihongyu.com/

你可能感兴趣的文章
外勤365:提升企业线下销售效率,成就移动外勤首选品牌
查看>>
防范网络犯罪组合拳 警企合作是关键
查看>>
黑客入侵好莱坞越发失控 黑客组织高调发声明威胁
查看>>
结合重复数据删除和Rowhammer的攻击怎么解?
查看>>
携手美国糖尿病协会,IBM将用大数据改变糖尿病的未来
查看>>
再续 asp.net 域名欺骗式开发之泛解析域名
查看>>
先是山寨后是烂大街 联发科的症结在哪?
查看>>
Snapchat升级聊天功能:增加贴纸、语音和视频
查看>>
5000万美元融资构建产业链!EasyStack深耕开源云
查看>>
因为你没加密 所以网络保险不给你理赔
查看>>
iOS零日漏洞赏金已升至150万美元
查看>>
印媒:中国厂商势头强劲 索尼三星在印度裁员
查看>>
苹果不再披露广告支出 或为掩饰销售额背后的支出增长
查看>>
中国太阳能续增 补贴、技术转型均受重视
查看>>
北京信息化协会人工智能专委会成立 AI产业快速腾飞
查看>>
《PostgreSQL服务器编程》一一1.9 关于缓存
查看>>
IBM芯片计划:生物是设计更高效芯片的关键
查看>>
没有这个黑客,就不会有你现在用的开源软件
查看>>
传统管理软件走在“生死边缘”,突围SaaS向死而生?
查看>>
这些数据科学技能,才是老板们最想要的
查看>>