Javascript数据结构与算法学习(四)——集合

什么是集合?

回顾之前的数据结构:栈,队列,链表——它们都可以用JS数组来实现,而集合的实现更依赖于Object,相较于对象key:value的结构,集合的key与value其实是同一个,即{1:1,2:2,'a':'a'}这种。参考ES6的Set数据结构

  • 特性:
    1. 无重复性:每个元素是互斥的
    2. 无序性:一个集合中,每个值钱经的地位都相同,元素之间是无序的。
    3. JS中集合的表示:对象

集合操作方法

  • 是否存在:has(value)
  • 删除:remove(value)
  • 添加:add(value)
  • 索引:indexOf()
  • 清空:clear()
  • 长度大小:size
function SetClass(){
    var items= {}
    this.has = function(val){
        return items.hasOwnProperty(val)
    }
    this.add = function(val){
        if(!this.has(val)){
            items[val]=val; // 以值 为key
            return val
        }
        return false
    }
    this.remove = function (value){
        if(!this.has(value)){
            delete items[value]
            return true;
        }
        return false;
    }
    this.clear=function(){
        items = {}
    }
    this.size = function(){
        return Object.keys(items).length;
    }
    this.values = function(){
        var values = []
        for(let key in items){
            if(items.hasOwnProperty(items[i])){
                values.push(items[i])
            }
        }
        return values
    }
    this.print = function(){
        console.log(items)
    }
} 

集合间的操作

在这里插入图片描述

  • 并集:union
  • 交集:intersection
  • 差集:difference

并集

在这里插入图片描述

 this.union = function (otherSet){
       var resSet = new SetClass()
       var arr = this.values()
       for(let i=0;i<arr.length;i++){
           resSet.add(arr[i])
       }
       arr = otherSet.values()
       for(let i=0;i<arr.length;i++){
           resSet.add(arr[i])
       }
       return resSet
   }

交集

this.intersection = function(otherSet){
        var resSet = new SetClass()
        var arr = this.values()
        for(let i=0;i<arr.length;i++){
            if(!otherSet.has(arr[i])){
                resSet.add(arr[i])
            }
        }
        return resSet
    }

差集

 this.differenct = function(otherSet){
        var resSet = new SetClass()
        let values = this.values()
        for(let i=0;i<values.length;i++){
            if(!otherSet.has(values[i])){
                resSet.add(values[i])
            }
        }
        return resSet
    }

ES6 内置新数据结构

  • Set : 集合
  • WeakSet: 弱集合, 只能添加一个object类型的值作为元素

相关API操作
在这里插入图片描述

var set = new Set(([1,2,3]))
set.forEach((key,value,set)=>{
    console.log('key---',key)
    console.log('value---',value)
    console.log(set)
})

var weakSet = new WeakSet()
weakSet.add('1') //报错
weakSet.add({name:'a'})

ES6实现交集、并集,差集

var set1 = new Set(([1,2,3]))
var set2 =new Set([2,3,4])

// 交集
var intersect = new Set([...set1].filter(item=>set2.has(item)))
// 差集
var different = new Set([...set2].filter(item=>!set1.has(item)))
// 并集
var union = new Set([...set1,...set2])

Set 和 WeakSet的区别

  • Set的强引用和WeakSet的弱引用
    在这里插入图片描述

如上图,声明一个变量obj指向了对象{name:''ceshi},将obj添加到set结构中后,改变obj的指向到null,此时,原Set结构因为是强引用指向原对象,所以该对象不会被 GC回收,仍然保留在内存中,直到使用set.delete删除掉该对象后才能解除引用。而weakSet则是在obj指向改变后,原object会忽略weakset的弱引用而直接被GC回收

  • 应用场景:开发中,使用weakSet更灵活,对内存的管理更自动化一些。

一道 ES6面试题

介绍下Set、Map、WeakSet和WeakMap的区别?

  • Set:
    • 成员不能重复
    • 只有键值,没有键名
    • 可以遍历,方法有add,delete,has
  • WeakSet:
    • 成员都是对象
    • 成员都是弱引用,随时可以消失,可以用来保存DOM节点,不容易造成内存泄漏
  • Map:
    • 本质上是键值对的集合,类似集合。其键名可以是非字符串.Object的键值对中的“键”实际是字符串,而Map的键可以是其他类型的值。
    • 可以遍历、
  • WeakMap:
  • 只接受对象作为键名(null除外),不接受其他类型的值作为键名
  • 键名所指向的对象,不计入垃圾回收机制
  • 不能遍历,方法有get、set、has、delete
发布了114 篇原创文章 · 获赞 146 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Sophie_U/article/details/103810451