js数组去重

188 阅读2分钟

介绍

简单的数组去重包括全匹配去重,对象数组根据单一字段去重,复杂去重包括对象数组根据多字段联合匹配去重

简单数组去重实现

1、全匹配去重

常用方法:有Set去重、filter去重、for循环去重等,具体实现如下:

Set去重

const unique(arr)=>{
    return [...new Set(arr)]
}

数组的filter方法去重

const unique(arr)=>{
    let obj={}
    return arr.filter(item=>{
        if(!obj[item]){
            obj[item]=true
            return true
        }
    })
}
​

数组for循环去重

const unique(arr)=>{
    let result = [];
    arr.forEach(item => {
        if (result.indexOf(item) == -1) {
            result.push(item)
        }
    })
    return result;
}
2、对象数组去重
  • 单属性相同的,保留第一个,其它的删除-- for循环方法

     const unique = (arr,prop) => {
            let newArr = []
            let obj = {};
            for (var i = 0; i < arr.length; i++) {
              if (!obj[arr[i][prop]]) {
                newArr.push(arr[i]);
                obj[arr[i][prop]] = true;
              }
            }
            return newArr
          };
    
  • 单属性相同的,保留第一个,其它的删除-- reduce方法

     const unique = (arr,prop) => {
            let obj = {};
              arr = arr.reduce((newArr, next) => {
                obj[next[prop]] ? "" : (obj[next[prop]] = true && newArr.push(next));
                return newArr;
              }, []);
              return arr;
          };
    
  • 使用lodash去重

    import _ from "lodash";
    let newArr=[..._.uniqBy(arr, prop)]//arr 是需要去重的数组、prop是要根据那个字段去重如"id"
    

复杂去重

对象数组联合字段去重

//示例数组
  let arr = [
      { id: 0, name: '张三', age: 16 },
      { id: 1, name: '李四', age: 14 },
      { id: 2, name: '王五', age: 13 },
      { id: 3, name: '赵六', age: 15 },
      { id: 1, name: '李四', age: 16 },
      { id: 2, name: '周八', age: 15 },
      { id: 2, name: '周八', age: 13 },
      { id: 3, name: '郑十', age: 16 }
    ]
  • 双重for循环

    const unique=(arr,props)=>{
        let result = []
        arr.forEach((item) => {
          if (result.length === 0) {
            result.push(item)
          } else {
            let isDiff = true //是否不同
            for (let i = 0; i < result.length; i++) {
              let dataItem = result[i]
              let isEqual = true //是否所有字段都相等
              for (const key of props) {
                isEqual = dataItem[key] === item[key]
                if (!isEqual) break // 有不相等的则退出该循环
              }
              if (isEqual) {// 全部相等时
                /*集合中已经存在相同数据*/
                isDiff = false
                break
              }
            }
            if (isDiff) { //有不同的则添加
              result.push(item)
            }
          }
        })
        return result
    }
    unique(arr, ['id', 'name']) 
    
  • 通过reduce方法:

    export function arrayUniqByMore(arr:Array<any>,props:Array<string>){
      let obj = {};
      let reduce = arr.reduce((curr, next) => {
        let key=""
        props.map(prop=>{
          key += next[prop]
        })
        /*判断对象中是否已经有该属性  没有的话 push 到 curr数组*/
        obj[key] ? '' : obj[key] = curr.push(next);
        return curr;
      }, []);
      return reduce
    }
    arrayUniqByMore(arr, ["id","name"]);
    
  • 使用 Lodash 中的 unionWith

    import _ from "lodash";
    const unique = (arr, props) => {
        return _.unionWith(arr, (item1: any, item2: any) => {
          let isEqual = true //是否所有字段都相等
          for (const key of props) {
            isEqual = item1[key] === item2[key]
            if (!isEqual){return false} // 有不相等的则退出该循环
          }
          return true;
        });
      }
    unique(arr, ['id', 'name']) 
    

扫码_搜索联合传播样式-标准色版.png