项目常用函数(一)之去重

117 阅读3分钟

前置:

前言:常用函数可以帮我们解决大量的数据问题,同时给我们带来解决的思路和灵感。正所谓函数就是程序员的一把屠龙宝刀,一刀99999。

  • 编辑器:vscode
  • 插件:JavaScript(ES6)、Code Runner(运行js文件)

Code Runner使用方法:右键Run Code运行js代码。如图:

1658802461271.jpg

注意:

  • 简单的必须要会手写
  • 进阶的可以选择性会手写
  • 进阶困难的就不要为难自己啦

一、去重

1. 数组去重(简单)

  • ES6--扩展运算符
  • ES6--new Set()
let arr = [1, 2, 2, 2, 7, 7, 7, 7, 7, 8, 9, 2, 1, 5, 7, 6]

let SetArr = [...new Set(arr)]
console.log(SetArr)      //[1, 2, 7, 8,9, 5, 6]

2. 数组对象去重(进阶)

场景一(频繁)

数组对象

image.png

处理后结果

1658815810152.jpg

1.Map()(推荐)

首先,我们对数组对象里面的属性a进行值去重,通过ES6的new Map()的has、set和values方法。

  • has方法可以判断Map对象中是否存在指定元素,有则返回true,否则返回false
  • set方法可以向Map对象添加新元素 map.set(key, value)
  • values方法可以返回Map对象值的遍历器对象
let result = []
let map = new Map()
for (const item of arrObj) {
  if (!map.has(item['a'])) {
    map.set(item['a'], item)
  }
}
result = [...map.values()]
console.log(result)
// [
//   { a: 1, b: 3 },
//   { a: 5, b: 2 },
//   { a: 8, b: 2 },
//   { a: 7, b: 10 },
//   { a: 9, b: 10 }
// ]

从上面代码中,我们已经对a属性进行了一次值去重,但是我们还要对b属性进行一次,虽然我们可以用上面代码再进行一次值去重,只需要把a改为b就行,但是会做重复的工作。那这刚刚好就符合递归的思维,因此我们对代码进行一次封装。

function arrObjSet(arrObj, arr = []) {
  if (arr.length > 1) {
    arrObj = arrObjSet(arrObj, arr.shift())
  }
  let attribute = arr[0]
  let result = []
  let map = new Map()
  for (const item of arrObj) {
    if (!map.has(item[attribute])) {
      map.set(item[attribute], item)
    }
  }
  result = [...map.values()]
  return result
}

console.log(arrObjSet(arrObj, ['a', 'b']));
// [ 
//   { a: 1, b: 3 }, 
//   { a: 5, b: 2 }, 
//   { a: 7, b: 10 } 
// ]

以上,我们很简单的进行了一次数组对象多属性值去重,有遇到这种情况的同学不会就可以直接上这个工具函数了。

2.嘿嘿,交给你们来吧,评论区写下你们想到的方法

场景二(少见)

数组对象

image.png

处理后结果

image.png

1.Object.assign()

首先,我们对数组对象里面的所有元素的属性进行聚合去重,然后再返回成数组的元素,通过ES6的Object.assign()和js的数组reverse()和unshift()方法。

  • Object.assign():将所有可枚举Object.propertyIsEnumerable() 返回 true)和自有Object.hasOwnProperty() 返回 true)属性从一个或多个源对象复制到目标对象,返回修改后的对象。(来源MDN网站)
  • reverse():反转数组中元素的顺序
  • unshift():在数组的前面添加一个元素

各位小伙伴们可以思考一下为什么要用reverse()

function arrObjSet_1(arrObj) {
    let obj = Object.assign(...(arrObj.reverse()))
    var arrObjSet = []
    for (const i of Object.keys(obj)) {
      let object = {}
      object[i] = obj[i]
      arrObjSet.unshift(object)
    }
    return arrObjSet
  }
console.log(arrObjSet_1(arrObj))
// [ { a: 1 }, { b: 3 }, { c: 78 } ]

以上代码可以用 for in,更加方便

2.Object.prototype.hasOwnProperty.call()

  • Object.prototype.hasOwnProperty.call():判断对象上是否存在这个属性。
  • unshift():在数组的前面添加一个元素
function arrObjSet_2(arrObj) {
    let resultObj = {}
    let resultArr = []
    for (const obj of arrObj) {
      for (const key in obj) {
        if (!Object.prototype.hasOwnProperty.call(resultObj, key)) {
          let object = {}
          object[key] = obj[key]
          resultObj[key] = arrObj[key]
          resultArr.unshift(object)
        }
      }
    }
    return resultArr
  }
 console.log(arrObjSet_2(arrObj))
 // [ { a: 1 }, { b: 3 }, { c: 78 } ]

上面的Object.prototype.hasOwnProperty.call() 可以写成 Object.hasOwnProperty.call(),因为它是Object原型上面的属性方法,可以通过原型链向上寻找,但是写Object.hasOwnProperty.call()时是没有提示的。同时Object.prototype.hasOwnProperty.call(resultObj, key)也可以改成ES6的新特性Object.hasOwn(resultObj, key)。(原型链、Object.hasOwn())

欢迎小伙伴们写下更多方法哟,评论区见。