在对数组进行过滤,想要得到这些数据包含的所有的类别,需要对数组里面的数据去重。例如我有一堆衣服的数据,这个数据里面包含了衣服的颜色和尺码等信息,我想得到所有衣服的所有的颜色种类,可以想到用函数式编程的方法,先得到有重复的颜色的数组,然后就需要对这个有重复的数组去重。这里的去重有两种,一种是基本类型的去重,另外一种更为复杂,数组里面的数据是对象。我们先看对第二种数组的去重。

字典类型的数组的去重

说到去重,就有一个问题,那就是什么时候判定为是重复的,也就是什么情况下两个数据是相等的。这里对于基本类型的数据好说,例如字符串或者数字,只要他们的值和类型都相等,我们就说他们是重复的。可是对于两个对象呢?怎么判断它们的值是否相等?直接通过===比较符可以吗?肯定是不行的,因为对象的===比较的是他们在内存中的位置信息,所以即使是对象里面的属性和方法都相等,通过===比较的结果也很可能为false。

如何判断两个对象是否相等(这里指有着相同的属性值和方法)?

lodash提供了一个isEqual的方法判断两个对象是否相等

_.isEqual(value, other)

而对于来自服务器的字典类型的对象数据,可以通过比较ID值来判断两个字典类型的数据是否相等。

那么,对象类型的数组去重的方法就有了

tableData.reduce((x, {materialType}) =>
  ((x.findIndex(t => t.ID === materialType.ID)>-1)? x: [...x, materialType]), [])
// or
this.tableData.reduce((x, {materialType}) =>
  ((x.some(t => _.isEqual(t, materialType))? x: [...x, materialType]), [])

简单类型的数组的去重

有多种方法可以对简单类型的数组去重。

1. filter方法过滤

let uniqueArr = (arrArg) => arrArg.filter((elem, pos, arr) => arr.indexOf(elem) == pos)

2. 利用ES6的Set类型

new Set([1, 2, 3, 1, 2, 3]).toJSON()
// 或者利用展开
[ ...new Set([1, 2, 3, 1, 2, 3]) ] // [1, 2, 3]

3. 用reduce来拼接不重复的值

[11, 22, 22, 33].reduce((x, y) => x.includes(y) ? x : [...x, y], [])

总的来说,对数组去重就是利用一个迭代的方法去判断新数组里面有无当前的数据,如果有就忽略并且next,如果无就拼接到新数组并且next,直到迭代完成并且返回这个新数组。