我们之前看过了 手写数组去重、扁平化函数 ,以及 不产生新数组,删除数组里的重复元素 ,这里再次加深一下,假如是数组元素包含对象等类型,又该如何去重喃?
示例如下:
[123, "meili", "123", "mogu", 123] ,则输出: [123, "meili", "123", "mogu"][123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"] ,则输出: [123, [1, 2, 3], [1, "2", 3], "meili"][123, {a: 1}, {a: {b: 1}}, {a: "1"}, {a: {b: 1}}, "meili"] ,则输出: [123, {a: 1}, {a: {b: 1}}, {a: "1"}, "meili"]const removeDuplicates = (arr) => { let map = new Map(); arr.forEach((item) => { map.set(JSON.stringify(item), item); }); return [...map.values()];};// 测试removeDuplicates([123, "meili", "123", "mogu", 123]);// [123, "meili", "123", "mogu"]removeDuplicates([123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"]);// [123, [1, 2, 3], [1, "2", 3], "meili"]removeDuplicates([ 123, { a: 1 }, { a: { b: 1 } }, { a: "1" }, { a: { b: 1 } }, "meili",]);// [123, {a: 1}, a: {b: 1}, {a: "1"}, "meili"]使用 JSON.stringify ,假如数组元素是 object 类型且里面键的顺序不同则会认为是两个不同放入数组元素
let o1 = { a: 1, b: 2 };let o2 = { b: 2, a: 1 };JSON.stringify(o1);// "{"a":1,"b":2}"JSON.stringify(o2);// "{"b":2,"a":1}"JSON.stringify(o1) === JSON.stringify(o2);// false处理思路:
一个数组(包含对象等类型元素)去重函数,需要在基础类型判断相等条件下满足以下条件:
去重本身就是遍历数组,而后比较数组中的每一项能否相等而已,所以关键步骤有两步:比较、去重
比较:
=== 比较去重:
reduce 去重,初始 accumulator 为 []findIndex 找到 accumulator 能否包含相同元素,假如不包含则加入,否则不加入accumulator ,则为去重后的数组代码实现:
// 获取类型const getType = (function () { const class2type = { "[object Boolean]": "boolean", "[object Number]": "number", "[object String]": "string", "[object Function]": "function", "[object Array]": "array", "[object Date]": "date", "[object RegExp]": "regexp", "[object Object]": "object", "[object Error]": "error", "[object Symbol]": "symbol", }; return function getType(obj) { if (obj == null) { return obj + ""; } // javascript高级程序设计中提供了一种方法,可以通用的来判断原始数据类型和引用数据类型 const str = Object.prototype.toString.call(obj); return typeof obj === "object" || typeof obj === "function" ? class2type[str] || "object" : typeof obj; };})();/** * 判断两个元素能否相等 * @param {any} o1 比较元素 * @param {any} o2 其余元素 * @returns {Boolean} 能否相等 */const isEqual = (o1, o2) => { const t1 = getType(o1); const t2 = getType(o2); // 比较类型能否一致 if (t1 !== t2) return false; // 类型一致 if (t1 === "array") { // 首先判断数组包含元素个数能否相等 if (o1.length !== o2.length) return false; // 比较两个数组中的每个元素 return o1.every((item, i) => { // return item === target return isEqual(item, o2[i]); }); } if (t2 === "object") { // object类型比较相似数组 const keysArr = Object.keys(o1); if (keysArr.length !== Object.keys(o2).length) return false; // 比较每一个元素 return keysArr.every((k) => { return isEqual(o1[k], o2[k]); }); } return o1 === o2;};// 数组去重const removeDuplicates = (arr) => { return arr.reduce((accumulator, current) => { const hasIndex = accumulator.findIndex((item) => isEqual(current, item)); if (hasIndex === -1) { accumulator.push(current); } return accumulator; }, []);};// 测试removeDuplicates([ 123, { a: 1 }, { a: { b: 1 } }, { a: "1" }, { a: { b: 1 } }, "meili", { a: 1, b: 2 }, { b: 2, a: 1 },]);// [123, {a: 1}, a: {b: 1}, {a: "1"}, "meili", {a: 1, b: 2}]原文链接:实现一个数组(包含对象等类型元素)去重函数