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

015题: 去重的几种方式 #15

Open
470772345 opened this issue Feb 24, 2021 · 0 comments
Open

015题: 去重的几种方式 #15

470772345 opened this issue Feb 24, 2021 · 0 comments

Comments

@470772345
Copy link
Owner

470772345 commented Feb 24, 2021

方式1 ES6新语法

还记得我们在 #13 提到的的吗

过滤出网页中不重复的html标签 结合去重知识点考查

[...new Set([...document.querySelectorAll('*')].map(v=>v.tagName))]

const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {},Symbol(1),Symbol(1)]

function getUni(arr){
    return Array.from(new Set(arr))
}
// 调用输出接口 发现有2个Symbol(1)   他们是不相等的 ,所以这个去重方式还是可以的
getUni(arr)
//  [1, "1", 17, true, false, "true", "a", {…}, {…}, Symbol(1), Symbol(1)]
//  空{}对象没有去重  (因为两个对象其实,引用不一样,所以也是不一样的. 后续方法我们研究可以去掉的)

那么此方式可以对对象去重吗??? 我们一起来验证下

const b={a:2}
let arr1 = [{a:1}, b, b, {a:3}];  //[{a:1},{a:2},{a:2},{a:3}]
let set1 = new Set(arr1);
let newArr1 = Array.from(set1);
console.log(newArr1); // [{a:1},{a:2},{a:3}]

//无法对象去重:
let arr2 = [{a:1}, {a:2}, {a:2}, {a:3}];  //[{a:1},{a:2},{a:2},{a:3}]
let set2 = new Set(arr2);
let newArr2 = Array.from(set2);
console.log(newArr2); //[{a:1},{a:2},{a:2},{a:3}]

方式2 遍历 利用filter

const unique = arr=>{
    return  arr.filter((item ,index)=>{
        // console.log(arr.indexOf(item))
        // indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,
        // 如果不存在,则返回-1
        return arr.indexOf(item) === index
    })
}
//  使用 includes , indexOf  的思路大致一样都是判断,是否存在,没有就添加.
//  使用filter+indexOf 的方式   ,对象也没有去重

方式3 使用 new Map() + for循环

const unique1= arr=>{
    const map = new Map()
    const res = []
    for(let i =0; i<arr.length;i++){
        if(!map.has(arr[i])){
            map.set(arr[i],true)
            res.push(arr[i])
        }
    }
    return res;
}

请注意!为Map设置对象属性也是可以的,但是可能引起大量的混乱。 下面我们来比较下

为Map设置对象属性方式

let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'

console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
// ...但是,这样做的话,它的行为会不符合预期:

wrongMap.has('bla')    // false
wrongMap.delete('bla') // false
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }

正确的方式

let myMap = new Map()
myMap.set('bla','blaa')
myMap.set('bla2','blaa2')
console.log(myMap)  // Map { 'bla' => 'blaa', 'bla2' => 'blaa2' }

myMap.has('bla')    // true
myMap.delete('bla') // true
console.log(myMap)  // Map { 'bla2' => 'blaa2' }

我们在控制器输入比较下,就比较直观

let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
"blaa"
wrongMap 
Map(0) {bla: "blaa"}
wrongMap.has('bla')
false
wrongMap.set('a','aaa')
Map(1) {"a" => "aaa"}
wrongMap
Map(1) {"a" => "aaa"}[[Entries]]0: {"a" => "aaa"}key: "a"value: "aaa"bla: "blaa"size: (...)__proto__: Map
wrongMap.has('a')
true

利用 hasOwnProperty

const  unique4 = ( arr )=> {
       let obj = {}
       return arr.filter((item,curIndex,arr)=>{
                 let tempFlag
                   if(typeof(item) === 'symbol'){
                     
                       tempFlag = typeof(item) + typeof(item)  
                   }else if(typeof(item)=== 'object'){
                       tempFlag = typeof(item) + JSON.stringify(item)
                   }else{
                        tempFlag = typeof(item) + item
                   }
                   
                  console.log(`tempFlag:${tempFlag}`)
                 
                 return obj.hasOwnProperty( tempFlag ) ? false : obj[tempFlag] = true;
       })}

// 这里利用给obj添加属性来去重.  是根据类型,去重的,也就是说 Symbol(1)   Symbol(666) 或则 {}, {}  也只会保留一个.
//  对symbol 去重,其实没有什么实际的意义, 而对象本来是引用类型,长得一样,
// 其实地址也不一样,但想把内容一致的去掉,lodash有比较两对象内容是否一致的.  
// _.unionWith([arrays],[comparator]), 指定哪几个字段作为去重条件, 不然有点浪费性能 
https://www.lodashjs.com/docs/lodash.unionWith

image

可以看出使用set添加的 是在 [[Entries]] 里面的,并且有对应的索引

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

1 participant