经常会遇到一些业务场景会需要我们对一个数组进行去重,基本数据类型的一维数组比较好办,使用reduce方法扫一遍即可实现去重,但是很多时候是通过后端返回一些数据,如果后端没有进行去重的操作,那么就只能把锅甩到前端了。。。
场景
例如现在从后端接收到了一串数据:
let arr = [{a: '1234',b: '5678'},{a: '1234',b: '56178'},{a: '1234',b: '5678'},{a: '1234',b: '51123678'},{a: '1234',b: 'abc'},{b: 'abc',a: '1234'}]
里面有一些数据是重合的,因此需要进行去重处理,有些可能会立马想到使用JSON.stringify方法将两两转换成字符串做全等匹配,但是这样是不靠谱的,因为json对象中key是无序的,只要键值对稍微调换一下位置就会出错。
目前我只想到最笨的方法,就是利用冒泡排序的思想,将数组中所有的数据都进行两两匹配,将两个对象中的键值对依次匹配,如果两个对象中属性值相等的次数等于了对象中的所有属性个数,说明两个对象中的值完全相等。
方法1
let flag = 0;for (let i = 0; i < arr.length; i++) {for (let j = i + 1; j < arr.length; j++) {let pre = arr[i];let next = arr[j];for (let key in pre) {// 有一个属性相等,flag+1if (pre[key] === next[key]) {flag++;}}// 如果相等的属性个数为一个对象的全部属性个数,说明完全重合if (flag === Object.keys(pre).length) {arr.splice(j, 1);}// 清除一个之后flag清零重新计数flag = 0;}}
方法2
function isObjEqual(o1, o2) {let props1 = Object.getOwnPropertyNames(o1);let props2 = Object.getOwnPropertyNames(o2);if (props1.length !== props2.length) {return false;}for (let i = 0, max = props1.length; i < max; i++) {let propName = props1[i];if (o1[propName] !== o2[propName]) {return false;}}return true;}let newArr = arr.reduce((prev, cur) => {let flag = false;for (let i = 0, len = prev.length; i < len; i++) {if (isObjEqual(prev[i], cur)) {flag = true;}}if (!flag) {prev.push(cur);}return prev;}, [])
注意点
以上提到的两种方法仅针对于以上指定场景中的情况,并且对象中的属性个数完全相等,并且数组中每个对象中的值都为基本数据类型。
