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中已经有了很多工具方法,所以可以拿来直接使用,比如restArgsflattenuniq。为什么强调这几个方法呢?因为使用这几个方法就可以实现数组求并集。

我们的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源码解析:GitHub

利用Underscore求数组的交集、并集和差集的更多相关文章

  1. 求数组差/交集函数-php数组函数(二)

    求数组差集函数 函数只检查了多维数组中的一维.可以用 array_diff($array1[0], $array2[0]) 检查更深的维度. u:自定义函数比较,a(association):同时比较 ...

  2. List集合中的交集 并集和差集

    目录 List集合求交集 并集 差集 Set集合 Lambda表达式 List集合求交集 并集 差集 两种方法求集 Set集合 交集 两个集合中有相同的元素 抽取出来的数据就是为交集 @Test pu ...

  3. PHP使用array_intersect()函数求数组交集

    在PHP中求数组的交集,我们可以与PHP给我们提供的现成函数:array_intersect(),其用法格式为: array array_intersect(array array1,array ar ...

  4. JavaScript求数组中元素的最大值

    要求: 求数组[2,6,1,77,52,25,7]中的最大值. 实现思路: 声明一个保存最大元素的变量 max 默认最大值max定义为数组中的第一个元素arr[0] 遍历这个数组,把里面每个数组元素和 ...

  5. java求字符串数组交集、并集和差集

    import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Ma ...

  6. JS 对象 数组求并集,交集和差集

    一.JS数组求并集,交集和差集 需求场景 最近,自己项目中有一些数组操作,涉及到一些数学集的运算,趁着完成后总结一下. 简化问题之后,现有两数组a = [1, 2, 3],b = [2, 4, 5], ...

  7. java使用bitmap求两个数组的交集

    一般来说int代表一个数字,但是如果利用每一个位 ,则可以表示32个数字 ,在数据量极大的情况下可以显著的减轻内存的负担.我们就以int为例构造一个bitmap,并使用其来解决一个简单的问题:求两个数 ...

  8. python中对两个 list 求交集,并集和差集

    python中对两个 list 求交集,并集和差集: 1.首先是较为浅白的做法: >>> a=[1,2,3,4,5,6,7,8,9,10] >>> b=[1,2,3 ...

  9. java用最少循环求两个数组的交集、差集、并集

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List ...

随机推荐

  1. 2.2、js基础---预解析和严格模式

    一.语言特性         1.预解析:js会把变量的声明(仅仅是声明)提到顶部,但是不会突破作用域.                 alert(a);var a= 12; //结果,undefi ...

  2. NOPI 导出 Excel 2007

    代码: public static void ThisTo<T>( List<T> source, string[] colums, Func<T, object[]&g ...

  3. 关于responseHeader的一些基础设置

    1.关于响应头的一些基础设置 //设置相应头 response.addHeader("name","zhangsan"); response.addIntHea ...

  4. Java基础(四)方法和数组

    一.方法 1.方法的定义 方法也叫函数,就是一个能独立完成某个功能的一段代码.方法可以看作一个整体. 语法: 修饰符 返回类型 方法名字(数据类型 变量名,数据类型 变量名,……[形式参数(0个到n个 ...

  5. Spring Cloud面试题

    引言 面试中面试官喜欢问组件的实现原理,尤其是常用技术,我们平时使用了SpringCloud还需要了解它的实现原理,这样不仅起到举一反三的作用,还能帮助轻松应对各种问题及有针对的进行扩展.以下是 课程 ...

  6. 译:Java局部变量类型推断(Var类型)的26条细则

    原文链接:https://dzone.com/articles/var-work-in-progress 作者:Anghel Leonard 译者:沈歌 Java局部变量类型推断(LVTI),简称va ...

  7. 自定义控件实现-今日头条Android APP图集效果

    前提 产品有个新需求,类似今日头条的图集效果 大致看了下UI,大致就是ViewPager,横向滑动切换图片,纵向滑动移动图片,纵向超过一定距离,图片飞出,图集淡出动画退出,支持图片的双击放大. 思路 ...

  8. javascript实现SHA1算法

    web里面密码直接传到后台是不安全的,有时候需要进行加密,找到一个不错的javascript SHA1算法: <!DOCTYPE html> <html lang="en& ...

  9. javascript获取元素样式值

    使用css控制页面有4种方式,分别为行内样式(内联样式).内嵌式.链接式.导入式. 行内样式(内联样式)即写在html标签中的style属性中,如<div style="width:1 ...

  10. HTML 简单日历制作方法

    新手一枚,不会写什么高大上的博文,一些平时做的小练习,献丑 <!doctype html> <html> <head> <meta charset=" ...