【多种、全 | 10余种】js 数组去重,来瞅瞅是不是你用到了那个

1,137 阅读7分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

数组去重

第一种(new Set && Array.from)

  • new Set() 和 Array.from() 这个是我最常用的
  • 优点:使用起来简单
  • 缺点: 不能对数组对象去重 基本用法:
const sourceArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
const targetArray = Array.from(new Set(sourceArray));
console.log(targetArray,'targetArray')
//输出去重后的数组: [1, 2, 3, 4, 5]

第二种(find)

  • find
  • 循环判断是否重复
//数字数组或者字符串数组(非对象数组)
const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let targetNumArray = [];
sourceNumArray.forEach(item => {
  const findItem = targetNumArray.find(child => child === item);
  //判断是否已经拥有、没有拥有就push进去
  if(!findItem) targetNumArray.push(item)
})

console.log(targetNumArray, 'targetNumArray');

//输出去重后的数组: [1, 2, 3, 4, 5]



//对象的数组find去重(对象数组)

//数组 (对象)
    const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
    let targetObjectArray = [];

    sourceObjectArray.forEach(item => {
     const findItem = targetObjectArray.find(child => JSON.stringify(child)=== JSON.stringify(item));
        if(!findItem) targetObjectArray.push(item)
    })   
   
 console.log(targetObjectArray,'targetObjectArray')
 
 //输出:[{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}]

用find 封装成公共去重函数

  • 兼容数组对象
  • 兼容数组字符串/数字
  • 兼容针对对象的某个字段去重
 /**
     * @dec find函数去重
     * @params source { Array } 必传 source 源数组
     * @params key { String } 非必传 (以数组对象的某个字段去重)
     * @return 去重后的数组
     */
    function findDeDuplicationPack(source, key) {
        let target = [];
        source.forEach((item) => {
            const findItem = target.find(child => {
                if(!key && JSON.stringify(child) === JSON.stringify(item)) {
                    return child
                }else if(key && child[key] === item[key]){
                   return child
                }
            });

            if(!findItem) target.push(item)
        })

        return target;
    }
const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]

//测试1、console.log(findDeDuplicationPack(sourceObjectArray),'sourceObjectArray')
//测试2、console.log(findDeDuplicationPack(sourceNumArray),'sourceNumArray')
//测试3、console.log(findDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')
//输出正确

第三种(some)

  • some
  • 也是循环判断利用some的方法实现去重处理

代码实现如下:

 //数组 (非对象)
   const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
   let targetNumArray = [];
   sourceNumArray.forEach(item => {
       const findItem = targetNumArray.some(child => child === item);
       if(!findItem) targetNumArray.push(item)
   })

   console.log(targetNumArray, 'targetNumArray');


     //数组 (对象)
   const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
   const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
   let targetObjectArray = [];
    

   sourceObjectArray.forEach(item => {
       const findItem = targetObjectArray.some(child => JSON.stringify(child) === JSON.stringify(item));
       if(!findItem) targetObjectArray.push(item)
   })

   console.log(targetObjectArray,'targetObjectArray')



   // 函数封装
   /**
    * @dec some函数去重
    * @params source { Array } 必传 source 源数组
    * @params key { String } 非必传 (以数组对象的某个字段去重)
    * @return 去重后的数组
    */
   function someDeDuplicationPack(source, key) {
       let target = [];
       source.forEach((item) => {
           const findItem = target.some(child => {
               if(!key && JSON.stringify(child) === JSON.stringify(item)) {
                   return child
               }else if(key && child[key] === item[key]){
                  return child
               }
           });

           if(!findItem) target.push(item)
       })

       return target;
   }
 
   console.log(someDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
   console.log(someDeDuplicationPack(sourceNumArray),'sourceNumArray')
   console.log(someDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第四种(findIndex)

  • findIndex 跟之前两种类似就是判断条件不一样
   //数组 (非对象)
   const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
   let targetNumArray = [];
   sourceNumArray.forEach(item => {
       const findItem = targetNumArray.findIndex(child => child === item);
       if(findItem === -1) targetNumArray.push(item)
   })

   console.log(targetNumArray, 'targetNumArray');


   //数组 (对象)
   const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
   const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
   let targetObjectArray = [];
    

   sourceObjectArray.forEach(item => {
       const findItem = targetObjectArray.findIndex(child => JSON.stringify(child) === JSON.stringify(item));
       if(findItem === -1) targetObjectArray.push(item)
   })

   console.log(targetObjectArray,'targetObjectArray')



   // 函数封装
   /**
    * @dec findIndex函数去重
    * @params source { Array } 必传 source 源数组
    * @params key { String } 非必传 (以数组对象的某个字段去重)
    * @return 去重后的数组
    */
   function findIndexDeDuplicationPack(source, key) {
       let target = [];
       source.forEach((item) => {
           const findItem = target.findIndex(child => {
               if(!key && JSON.stringify(child) === JSON.stringify(item)) {
                   return child
               }else if(key && child[key] === item[key]){
                  return child
               }
           });

           if(findItem === -1) target.push(item)
       })

       return target;
   }
 
   console.log(findIndexDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
   console.log(findIndexDeDuplicationPack(sourceNumArray),'sourceNumArray')
   console.log(findIndexDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第五种(every)

  • every 使用every实现去重

第六种(includes)

  • includes 实现数组去重
    //数组 (非对象)
    const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
    let targetNumArray = [];
    sourceNumArray.forEach(item => {
        const findItem = targetNumArray.includes(item);
        if(!findItem) targetNumArray.push(item)
    })

    console.log(targetNumArray, 'targetNumArray');


    //数组 (对象)
    const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
    const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
    let targetObjectArray = [], targetObjectStringArray = [];
    

    sourceObjectArray.forEach(item => {
        const findItem = targetObjectStringArray.includes(JSON.stringify(item))
        if(!findItem) {
            targetObjectArray.push(item);
            targetObjectStringArray.push(JSON.stringify(item))
        }
    })

    console.log(targetObjectArray,'targetObjectArray')



    // 函数封装
    /**
     * @dec includes函数去重
     * @params source { Array } 必传 source 源数组
     * @params key { String } 非必传 (以数组对象的某个字段去重)
     * @return 去重后的数组
     */
    function includesDeDuplicationPack(source, key) {
        let target = [], targetString = [];
        source.forEach((item) => {
            const findItem = targetString.includes(JSON.stringify(key ? item[key] : item))

            if(!findItem) {
                target.push(item);
                targetString.push(JSON.stringify(key ? item[key] : item))
            }
        })

        return target;
    }
  
    console.log(includesDeDuplicationPack(sourceObjectArray),'sourceObjectArray')
    console.log(includesDeDuplicationPack(sourceNumArray),'sourceNumArray')
    console.log(includesDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第七种(filter)

  • filter 实现数组去重
//数组 (非对象)
const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let targetNumArray = [];
sourceNumArray.forEach(item => {
    const filterItem = targetNumArray.filter(child => child === item);
    if(!filterItem.length) targetNumArray.push(item)
})

console.log(targetNumArray, 'targetNumArray');


//数组 (对象)
const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
let targetObjectArray = [];
 

sourceObjectArray.forEach(item => {
    const filterItem = targetObjectArray.filter(child => JSON.stringify(child) === JSON.stringify(item));
    if(!filterItem.length) targetObjectArray.push(item)
})

console.log(targetObjectArray,'targetObjectArray')



// 函数封装
/**
 * @dec filter函数去重
 * @params source { Array } 必传 source 源数组
 * @params key { String } 非必传 (以数组对象的某个字段去重)
 * @return 去重后的数组
 */
function filterDeDuplicationPack(source, key) {
    let target = [];
    source.forEach((item) => {
        const filterItem = target.filter(child => {
            if(!key && JSON.stringify(child) === JSON.stringify(item)) {
                return child
            }else if(key && child[key] === item[key]){
               return child
            }
        });

        if(!filterItem.length) target.push(item)
    })

    return target;
}

console.log(filterDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
console.log(filterDeDuplicationPack(sourceNumArray),'sourceNumArray')
console.log(filterDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第八种(map)

  • map实现数组去重
   //数组 (非对象)
const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let targetNumArray = [];
sourceNumArray.forEach(item => {
    const mapItem = targetNumArray.map(child => child === item);

    if(mapItem.every(child => !child) || mapItem.length === 0) targetNumArray.push(item)
})

console.log(targetNumArray, 'targetNumArray');


//数组 (对象)
const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
let targetObjectArray = [];
 

sourceObjectArray.forEach(item => {
    const mapItem = targetObjectArray.map(child => JSON.stringify(child) === JSON.stringify(item));
    if(mapItem.every(child => !child) || mapItem.length === 0) targetObjectArray.push(item)
})

console.log(targetObjectArray,'targetObjectArray')



// 函数封装
/**
 * @dec map函数去重
 * @params source { Array } 必传 source 源数组
 * @params key { String } 非必传 (以数组对象的某个字段去重)
 * @return 去重后的数组
 */
function mapDeDuplicationPack(source, key) {
    let target = [];
    source.forEach((item) => {
        const mapItem = target.map(child => {
            if(!key && JSON.stringify(child) === JSON.stringify(item)) {
                return true
            }else if(key && child[key] === item[key]){
               return true
            }
        });

        if(mapItem.every(child => !child) || mapItem.length === 0) target.push(item)
    })

    return target;
}

console.log(mapDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
console.log(mapDeDuplicationPack(sourceNumArray),'sourceNumArray')
console.log(mapDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第九种 (indexOf)

  • indexOf 实现数组去重
       //数组 (非对象)
    const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
    let targetNumArray = [];
    sourceNumArray.forEach(item => {
        const findItem = targetNumArray.indexOf(item);
        if(findItem === -1) targetNumArray.push(item)
    })

    console.log(targetNumArray, 'targetNumArray');


    //数组 (对象)
    const sourceObjectArray = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}]
    const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]
    let targetObjectArray = [], targetObjectStringArray = [];
    

    sourceObjectArray.forEach(item => {
        const findItem = targetObjectStringArray.indexOf(JSON.stringify(item))
        if(findItem === -1) {
            targetObjectArray.push(item);
            targetObjectStringArray.push(JSON.stringify(item))
        }
    })

    console.log(targetObjectArray,'targetObjectArray')



    // 函数封装
    /**
     * @dec indexOf函数去重
     * @params source { Array } 必传 source 源数组
     * @params key { String } 非必传 (以数组对象的某个字段去重)
     * @return 去重后的数组
     */
    function indexOfDeDuplicationPack(source, key) {
        let target = [], targetString = [];
        source.forEach((item) => {
            const findItem = targetString.indexOf(JSON.stringify(key ? item[key] : item))

            if(findItem === -1) {
                target.push(item);
                targetString.push(JSON.stringify(key ? item[key] : item))
            }
        })

        return target;
    }
  
    console.log(indexOfDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
    console.log(indexOfDeDuplicationPack(sourceNumArray),'sourceNumArray')
    console.log(indexOfDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第十种(更优雅、优化性能、快 new Map)


 const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];

  let sourceNumMap = new Map();
  let targetNumArray = [];
    sourceNumArray.forEach(item => {

        if(!sourceNumMap.get(item)) {
          targetNumArray.push(item);
          sourceNumMap.set(item, item);
        }
    })

    sourceNumMap.clear() //释放空间
    console.log(targetNumArray, 'targetNumArray');


    const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]

   // 函数封装
    /**
     * @dec new Map函数去重
     * @params source { Array } 必传 source 源数组
     * @params key { String } 非必传 (以数组对象的某个字段去重)
     * @return 去重后的数组
     */

     function newMapDeDuplicationPack(source, key) {
        let target = [];
        let targetMap = new Map()
        source.forEach((item) => {

            const setItem = key ? JSON.stringify(item[key]) : JSON.stringify(item);

            if(!targetMap.get(setItem)) {
                target.push(item);
                targetMap.set(setItem, item)
            }
        })

        targetMap.clear();

        return target;
    }

console.log(newMapDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
console.log(newMapDeDuplicationPack(sourceNumArray),'sourceNumArray')
console.log(newMapDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

第十一种(更优雅、优化性能、快 new Set)

  • new Set() 实现数组去重
  const sourceNumArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];

  let sourceNumSet = new Set();
  let targetNumArray = [];
    sourceNumArray.forEach(item => {

        if(!sourceNumSet.has(item)) {
          targetNumArray.push(item);
          sourceNumSet.add(item);
        }
    })

    sourceNumSet.clear() //释放空间
    console.log(targetNumArray, 'targetNumArray');


    const sourceObjectArray2 = [{name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小莉', id: 3}, {name: '小明', id: 1}, {name: '小红', id: 2}, {name: '小黑', id: 2}]


   // 函数封装
    /**
     * @dec new Set函数去重
     * @params source { Array } 必传 source 源数组
     * @params key { String } 非必传 (以数组对象的某个字段去重)
     * @return 去重后的数组
     */

     function newSetDeDuplicationPack(source, key) {
        let target = [];
        let targetSet = new Set();
        source.forEach((item) => {

            const setItem = key ? JSON.stringify(item[key]) : JSON.stringify(item);

            if(!targetSet.has(setItem)) {
                target.push(item);
                targetSet.add(setItem)
            }
        })

        targetSet.clear();

        return target;
    }

console.log(newSetDeDuplicationPack(sourceObjectArray2),'sourceObjectArray')
console.log(newSetDeDuplicationPack(sourceNumArray),'sourceNumArray')
console.log(newSetDeDuplicationPack(sourceObjectArray2, 'id'),'sourceObjectArray2')

结束语

  • 大家好 我是三原,多谢您的观看,我会更加努力(๑•̀ㅂ•́)و✧多多总结。
  • 每个方法都是敲出来验证过通过的,有需要可以放心复制。
  • 如果您给帮点个赞👍就更好了 谢谢您~~~~~
  • 期待您的关注