js数组对象去重同时判断两个属性条件相同去重

arr=[
 {
    maxDeptCode: "md3"
    maxDeptName: "泡泡"
    minDeptCode: "md301"
    minDeptName: "泡泡少儿"
    schoolId: 1
    schoolName: "北京"
 },
 {
    maxDeptCode: "md2"
    maxDeptName: "中学"
    minDeptCode: "md201"
    minDeptName: "中学一对一"
    schoolId: 1
    schoolName: "北京"
 },{
    maxDeptCode: "md3"
    maxDeptName: "泡泡"
    minDeptCode: "md301"
    minDeptName: "泡泡少儿"
    schoolId: 1
    schoolName: "北京"
 },
]

clipboard.png
当我选择的时候需要判断数组最大部门和最小部门两个都重复的对象,然后进行提示,已选择重复,同时去重,这种去重如何判断?请大神指点!

阅读 13k
5 个回答

基本思路就是遍历并记录,每次遍历是检查记录是否已经出现过,

方法一,用 Array.prototype.find

function process(arr) {
    // 缓存用于记录
    const cache = [];
    for (const t of arr) {
        // 检查缓存中是否已经存在
        if (cache.find(c => c.maxDeptCode === t.maxDeptCode && c.minDeptCode === t.minDeptCode)) {
            // 已经存在说明以前记录过,现在这个就是多余的,直接忽略
            continue;
        }
        // 不存在就说明以前没遇到过,把它记录下来
        cache.push(t);
    }

    // 记录结果就是过滤后的结果
    return cache;
}

方法二,用 Array.prototype.filter

function process2(arr) {
    // 需要一个字典,可以用 Set/WeakSet 或者就简单的 JS 对象
    const dict = {};

    // 过滤的过程中完善 dict
    return arr.filter(t => {
        // 根据 max 和 min 来生成唯一识别的关键字
        // 这里采用的办法是使用一个不会出现在两个数据中的字符 `|` 来连接
        const key = [t.maxDeptCode, t.minDeptCode].join("|");

        // 检查如果字典中已经存在,那这个数据就过滤掉,不需要了
        if (dict[key]) {
            return false;
        }

        // 如果字典不不存在,加入字典,同时把数据保留下来(返回 true)
        dict[key] = true;
        return true;
    });
}

使用java里面set去重的思路,也就是一个对象里面的key是唯一的。

const dict = {};
for (const item of arr) {
    dict[item.maxDeptCode + ',' + item.minDeptCode] = item;
}
arr = Object.values(dict);

和上面的几个思路类似,但是不需要判断

给一个你好理解的,当然肯定不是最优代码。思路就是两次循环遍历该数组,然后判断两次循环遍历的数组项是否相等,如果相等,则使用splice方法来删除该数组项。代码如下:

 for(let i = 0;i < arr.length;i++){
        for(let j = i + 1;j < arr.length;j++){
            for(let key in arr[i]){
                if(arr[i][key] === arr[j][key]){
                    arr.splice(i,1);
                    break;
                }
            }
        }
    }
    console.log(arr)

另外修正一下@前往火星中的代码,有一点点小问题,那里的key是没有定义的,所以你的filterKey,应该换成key。顺带解释一下@前往火星中的代码:
将代码拆分如下:

        Object.values(
            arr.reduce((data,item) => {
                let key = item.maxDeptName + item.minDeptName;
                if(!data[key]){
                    data[key] = item;
                }
                return data;
            },{})
        )
        

在理解这段代码,你需要了解reduceObject.values方法的用法及含义。Object.values就是枚举一个对象所有属性与属性值,然后返回一个数组,reduce就是循环过滤数组,传入五个参数,第一个代表这个方法最后返回的值,因为要枚举对象,所以这里的最后一个参数就代表最后返回的是一个对象。具体用法如下图所示:

clipboard.png

然后根据你所说的定义一个判断条件的key,如果key不存在,就往对象里面添加该对象,最后返回该对象。

引用别人一个例子

var hash = {};
arr = arr.reduce(function(targetData, item) {
    var filterKey = item.maxDeptName + item.minDeptName;
    hash[filterKey] ? '' : hash[filterKey] = true && targetData.push(item);
    return targetData
}, [])
Object.values(
    arr.reduce(
        (targetData, item) => { 
            var filterKey = item.maxDeptName + item.minDeptName;
            if(targetData[filterKey] === undefined) {
                targetData[filterKey] = item
            }; 
            return targetData; 
        }
        ,{}
    )
)
    let arr = [
      {
        maxDeptCode: 'md3',
        maxDeptName: '泡泡',
        minDeptCode: 'md301',
        minDeptName: '泡泡少儿',
        schoolId: 1,
        schoolName: '北京'
      },
      {
        maxDeptCode: 'md2',
        maxDeptName: '中学',
        minDeptCode: 'md201',
        minDeptName: '中学一对一',
        schoolId: 1,
        schoolName: '北京'
      },
      {
        maxDeptCode: 'md3',
        maxDeptName: '泡泡',
        minDeptCode: 'md301',
        minDeptName: '泡泡少儿',
        schoolId: 1,
        schoolName: '北京'
      }
    ]
    let result = arr.reduce((init, current) => {
      const maxCode = current.maxDeptCode
      const minCode = current.minDeptCode
      const index = `${maxCode}${minCode}`

      if (init.length === 0 || !init[index]) {
        init[index] = current
      }
      return init
    }, [])
    console.log(result)

clipboard.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏