学习链接

根据以下要求,写一个数组去重函数

数组去重

只考虑字符串和数字

Set

  1. function unique(arr) {
  2. return [...new Set(arr)];
  3. }

filter + indexOf

  1. function unique(arr) {
  2. return arr.filter((item, index, arr) => {
  3. return arr.indexOf(item) === index;
  4. });
  5. }

reduce + includes

  1. function unique(arr) {
  2. return arr.reduce((pre, cur) => {
  3. if(!pre.includes(cur)) {
  4. pre.push(cur);
  5. }
  6. return pre;
  7. }, []);
  8. }

测试

  1. const arr = [123, "meili", "123", "mogu", 123];
  2. console.log('unique(arr): ', unique(arr));

考虑对象

只考虑对象、不考虑属性顺序和NaN

  1. function unique(arr) {
  2. return [...new Set(arr.map(x => JSON.stringify(x)))].map(x => JSON.parse(x));
  3. }

数组去重 - 图1

数组去重 - 图2

考虑对象属性顺序、NaN、Infinity

  1. function unique(arr) {
  2. const getArray = data => {
  3. const str = Object.prototype.toString.call(data);
  4. if(data
  5. && (str === '[object Object]' || str === '[object Array]')
  6. ) { // 非空对象/数组
  7. const val = [];
  8. Object.keys(data).sort().forEach(k => { // 排序处理对象名顺序的问题
  9. val.push([k, getArray(data[k])]); // 递归处理值
  10. });
  11. return val;
  12. } else { // 原始类型 | null
  13. return data;
  14. }
  15. };
  16. const getType = data => {
  17. if(data === undefined
  18. || data === Infinity
  19. || data === -Infinity
  20. || Object.is(data, NaN)
  21. ) {
  22. return data;
  23. } else {
  24. return JSON.stringify(getArray(data));
  25. }
  26. };
  27. const arrStr = arr.map(item => ({
  28. val: item,
  29. type: getType(item)
  30. }));
  31. const map = new Map();
  32. return arrStr
  33. .filter(item => !map.has(item.type) && map.set(item.type, item.val))
  34. .map(item => item.val);
  35. }
  1. const arr1 = [123, "meili", "123", "mogu", 123];
  2. const arr2 = [123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"];
  3. const arr3 = [123, {a: 1}, {a: {b: 1}}, {a: "1"}, {a: {b: 1}}, "meili"];
  4. const arr4 = [{b: 1, c: 2}, {c: 2, b: 1}];
  5. const arr5 = [undefined, null, undefined, null];
  6. const arr6 = [NaN, Infinity, -Infinity, NaN, Infinity, -Infinity];
  7. const arr7 = [NaN, null];
  8. console.log('unique(arr1): ', unique(arr1));
  9. console.log('unique(arr2): ', unique(arr2));
  10. console.log('unique(arr3): ', unique(arr3));
  11. console.log('unique(arr4): ', unique(arr4));
  12. console.log('unique(arr5): ', unique(arr5));
  13. console.log('unique(arr6): ', unique(arr6));
  14. console.log('unique(arr7): ', unique(arr7));
  15. // 函数、日期对象、正则表达式无法正确去重
  16. function fun1(){let x = 5}
  17. function funny(){let z = 5}
  18. const date1 = new Date(1,1)
  19. const date2 = new Date(1,2)
  20. const arr8 = [fun1, funny];
  21. const arr9 = [/a/, /abc/];
  22. const arr10 = [date1, date2];
  23. console.log('unique(arr8): ', unique(arr8));
  24. console.log('unique(arr9): ', unique(arr9));
  25. console.log('unique(arr10): ', unique(arr10));

JSON也无法处理循环对象结构

一个思路