Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数组去重 #67

Open
Sunny-117 opened this issue Nov 3, 2022 · 5 comments
Open

数组去重 #67

Sunny-117 opened this issue Nov 3, 2022 · 5 comments

Comments

@Sunny-117
Copy link
Owner

大家都会吧,就不写了

@jlx2002
Copy link
Contributor

jlx2002 commented Jan 15, 2023

分享一个有意思的数组去重,有关引用类型的去重。
如果数组去重,涉及到对象引用问题,应该怎么解决?

类似于这种示例:

let a = {"a": 1};
let b = {"a": 1};
let c = {"b": 2};
let nums = [a, b, c];
uniq(nums) 
// 预计结果: [{"a": 1}, {"b": 2}] 

Set 去重 (失效):

let a = {"b": 1};
new Set([a, {"b": 1}]);
// Set(2)

image

/**
 * @description: 检查两个对象 obj1 和 obj2 是否值相等
 * @param {*} obj1
 * @param {*} obj2
 * @return {*}
 */
function checkObj(obj1, obj2) {
  // 指向同一内存
  if (obj1 === obj2) return true;
  let arr1 = Object.keys(obj1),
    arr2 = Object.keys(obj2);
  // 判断属性值是否相等
  if (arr1.length != arr2.length) return false;
  for (const k in arr1) {
    if (typeof arr1[k] == "object" || typeof arr2[k] == "object") {
      if (!checkObj(arr1[k], arr2[k])) return false;
    } else if (arr1[k] !== arr2[k]) {
      return false;
    }
  }
  return true;
}

/**
 * @description: 在数组原型上写方法
 * @param {*} itemObj
 * @return {*}
 */
Array.prototype.includesObj = function (itemObj) {
  let flag = false;
  for (let i = 0; i < this.length; i++) {
    if (checkObj(this[i], itemObj)) {
      flag = true;
      break;
    }
  }
  return flag;
};

/**
 * @description: 针对对象数组,且可能出现对象引用的问题
 * @param {*} nums
 * @return {*}
 */
function uniqSpecial(nums) {
  const result = [];
  for (let i = 0; i < nums.length; i++) {
    // 如果不存在
    if (!result.includesObj(nums[i])) result.push(nums[i]);
  }
  return result;
}
let a = { a: 1 };
let b = { a: 1 };
let c = { b: 2 };
let nums = [a, b, c];

console.log(uniqSpecial(nums));
// [ { a: 1 }, { b: 2 } ]

@hannah-bingo
Copy link
Contributor

        var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

        // 方法一: set
        let newArr = [...new Set(arr)]
        console.log(newArr);
        

        // 方法二:两层遍历+splice
        function unique(arr) {
            for(let i = 0; i < arr.length; i++) {
                for(let j = i+1; j < arr.length; j++){
                    if(arr[i] === arr[j]){
                        arr.splice(j, 1);    //会改变原来的arr
                        j--;
                    }  
                }
            }
            return arr;
        }
        console.log(unique(arr));
        console.log(arr);

        var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

        // 方法三 : filter+indexOf
        const newArr2 = [];
        arr.filter((item, index) =>{
            if(arr.indexOf(item) === index) {
                newArr2.push(item)
            }
        })
        console.log(newArr2);


        // 方法四 : includes
        let newArr3 = [];
        for (let i = 0; i<arr.length; i++) {
            if( !newArr3.includes(arr[i]) ) {
                newArr3.push(arr[i]);
            }
        }
        console.log(newArr3);

        // 方法五:filter + hasOwnProperty----------> 貌似有点点问题
        let obj = {}
        let result = arr.filter((item, index) => {
            return obj.hasOwnProperty(item) ? false : (obj[item] = true)
        })
        console.log(result);

@ych-chen
Copy link

// ES6方法

const array1 = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
Array.from(new Set(array1));

// ES5方法:使用map存储不重复的数字

const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];

function uniqueArray(array){
    let map = {}
    let res = []
    for(var i = 0; i < array.length; i++){
        if(!map.hasOwnProperty([array[i]])){
            map[array[i]] = i;
            res.push(array[i])
        }
    }
    return res;
}
uniqueArray(array);

@Banks1y
Copy link

Banks1y commented Jun 19, 2023

//数组去重
arr = [1, 3, 4, 4, 3, 1];
//set
console.log([...new Set(arr)]);
//filter
let res = arr.filter((item, index) => {
  return arr.indexOf(item) === index;
});
console.log(res);
//indexOf
let res2 = [];
arr.map((item) => {
  if (res2.indexOf(item) === -1) res2.push(item);
});
console.log(res2);

@kangkang123269
Copy link

数组去重的十种方法

  1. Set
let arr = [1, 2, 3, 2, 1];
let uniqueArr = [...new Set(arr)];
  1. Filter
let arr = [1, 2, 3, 2, 1];
let uniqueArr = arr.filter((item,index,array) => array.indexOf(item) === index);
  1. Reduce
let arr = [1, 2, 3 ,4 ,5 ,6];
const result=arr.reduce((unique,item)=>{
    return unique.includes(item)?unique:[...unique,item]
  },[]);
 console.log(result)
  1. Map
function uniq(arr){
    const res=new Map();
    return arr.filter(a=>!res.has(a)&&res.set(a,a))
  }
  uniq([0,-0,+0]) // 输出[0,-0]
  1. 双层循环 + splice
function dedupe(array){
let len=array.length;
for(let i=0;i<len;i++){
 for(let j=i+1;j<len;j++){
 if(array[i]==array[j]){
 array.splice(j--,1);
 }
 }
}
return array;
}
  1. 排序后相邻比较
function dedupe(array){
array.sort();
let temp=[];
for(let i=0;i<array.length;i++){
if( array[i] !== temp[temp.length-1]){
temp.push( array[i])
}
}
return temp;
} 
  1. 利用对象属性名称不能相同原理进行去重
function dedupe(array){ 
var n={},r=[]; //n为hash表,r为临时数组 
for(var i=0; i<array.length; i++) //遍历当前数组 
{ 
if (!n[array[i]]) //如果hash表中没有当前项 
{ 
n[array[i]] = true; //存入hash表 
r.push(array[i]); //把当前数组的元素存入临时数组中
 } 
} 

return r; 

}
  1. includes方法:判断新数组是否含有老数组的某一项,没有则push进新数组.
function dedupe(arr){
let newArr=[];
for(let i=0;i<arr.length;i++){
if(!newArr.includes(arr[i])){
newArr.push(arr[i]);
}
}
return newArr;
}
  1. lastIndexOf
function dedupe(array){
return array.filter((item,index,array)=>array.lastIndexOf(item)===index);
}
  1. every
function dedupe(array){
let newArr=[];
for(let i=0;i<array.length;i++){
if(newArr.every(item=>item!==array[i])){
newArr.push(array[i]);
}
}

return newArr;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants