JavaScript数据结构教程(3):集合
沉沙 2018-07-23 来源 : 阅读 1115 评论 0

摘要:集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体,这些对象称为该集合的元素。希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

集合简介

在上一篇JavaScript数据结构教程(2):链表中我们说了链表这种数据结构,但归根结底,不论是栈,队列亦或是链表都是线性结构。他们都是一种很规矩的数据结构,就像幼儿园的小朋友排队乖乖的站在那不会动一样。

 

然而纷杂的数据并不会总是排队站在那里,幼儿园小朋友一旦下了课那可就撒欢了,乱糟糟一团。可我们的幼儿园老师却能分辨出这些小朋友,因为啥?因为每个小朋友都在一个班里,而且每一个小朋友都有自己的名字。老师自然很容易就找到小朋友了。

 

而本篇要说的集合正是一堆乱糟糟的数据,唯一的共同点是这些数据隶属于同一个集合,看下百科给出的解释:

由一个或多个元素所构成的叫做集合。

此处的元素就是小朋友了,他们所在的集合就是他们的班级。其实我们在高中的时候也接触过集合的概念。那时候还没有套路这个名词,单纯的岁月,那个年代对于集合是这么解释的:

集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体,这些对象称为该集合的元素。

然后又是这么分类的:

· 空集:{}

· 有限集:{a,b,4}

· 无限集:{1,2,3,4…}

不过,数据结构中集合是没有无限集这个概念的。再然后那时候的集合还有这么几个特性:

· 确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。

· 互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。有时需要对同一元素出现多次的情形进行刻画,可以使用多重集,其中的元素允许出现多次。

· 无序性:一个集合中,每个元素的地位都是相同的,元素之间是无序的。集合上可以定义序关系,定义了序关系后,元素之间就可以按照序关系排序。但就集合本身的特性而言,元素之间没有必然的序。

集合还有这几种常见的基本操作:

· 并集

· 交集

· 差集

而且我们数据结构中的集合基本是也符合高中时候的数学中的概念的。接下来我们是用ES5来实现集合,为啥子这么说呢……因为在ES6中已经新给出了Set,Map等几个集合类,更加方便快捷的锁定键值对。

集合的创建

首先我们先声明一个集合类:

function(){

    var items={};

}

   


接下来,我们需要给链表声明一些方法:

· add(value):向集合添加一个新的项

· remove(value):从集合移除一个值

· has(value):如果值在集合中,返回true,否则返回false

· clear():移除集合中的所有项

· size():返回集合所包含的元素数量,与数组的length属性相似

· values():返回一个集合中所有值的数组

· union(setName):并集,返回包含两个集合所有元素的新集合(元素不重复)

· intersection(setName):交集,返回包含两个集合中共有的元素的集合、

· difference(setName):差集,返回包含所有存在本集合而不存在setName集合的元素的新集合

· subset(setName):子集,验证setName是否是本集合的子集

下面是Set类的完整代码:

function Set() {
    let items = {};
    this.add = function(value){
        if (!this.has(value)){
            items[value] = value;
            return true;
        }
        return false;
    };
    this.delete = function(value){
        if (this.has(value)){
            delete items[value];
            return true;
        }
        return false;
    };
    this.has = function(value){
        return items.hasOwnProperty(value);
        //return value in items;
    };
 
    this.clear = function(){
        items = {};
    };
    /**
     * Modern browsers function
     * IE9+, FF4+, Chrome5+, Opera12+, Safari5+
     * @returns {Number}
     */
    this.size = function(){
        return Object.keys(items).length;
    };
 
    /**
     * cross browser compatibility - legacy browsers
     * for modern browsers use size function
     * @returns {number}
     */
    this.sizeLegacy = function(){
        let count = 0;
        for(let key in items) {
            if(items.hasOwnProperty(key))
                ++count;
        }
        return count;
    };
    /**
     * Modern browsers function
     * IE9+, FF4+, Chrome5+, Opera12+, Safari5+
     * @returns {Array}
     */
    this.values = function(){
        let values = [];
        for (let i=0, keys=Object.keys(items); i<keys.length; i++) {
            values.push(items[keys[i]]);
        }
        return values;
    };
    this.valuesLegacy = function(){
        let values = [];
        for(let key in items) {
            if(items.hasOwnProperty(key)) {
                values.push(items[key]);
            }
        }
        return values;
    };
    this.getItems = function(){
      return items;
    };
    this.union = function(otherSet){
        let unionSet = new Set();
        let values = this.values();
        for (let i=0; i<values.length; i++){
            unionSet.add(values[i]);
        }
        values = otherSet.values();
        for (let i=0; i<values.length; i++){
            unionSet.add(values[i]);
        }
        return unionSet;
    };
    this.intersection = function(otherSet){
        let intersectionSet = new Set();
        let values = this.values();
        for (let i=0; i<values.length; i++){
            if (otherSet.has(values[i])){
                intersectionSet.add(values[i]);
            }
        }
        return intersectionSet;
    };
    this.difference = function(otherSet){
        let differenceSet = new Set();
        let values = this.values();
        for (let i=0; i<values.length; i++){
            if (!otherSet.has(values[i])){    
                differenceSet.add(values[i]);
            }
        }
        return differenceSet;
    };
    this.subset = function(otherSet){
        if (this.size() > otherSet.size()){
            return false;
        } else {
            let values = this.values();
            for (let i=0; i<values.length; i++){
                if (!otherSet.has(values[i])){  
                    return false;
                }
            }
            return true;
        }
    };
}
下面是ES6版本代码:
 
let Set2 = (function () {
    const items = new WeakMap();
    class Set2 {
        constructor () {
            items.set(this, {});
        }
        add(value){
            if (!this.has(value)){
                let items_ = items.get(this);
                items_[value] = value;
                return true;
            }
            return false;
        }
        delete(value){
            if (this.has(value)){
                let items_ = items.get(this);
                delete items_[value];
                return true;
            }
            return false;
        }
        has(value){
            let items_ = items.get(this);
            return items_.hasOwnProperty(value);
        }
        clear(){
            items.set(this, {});
        }
        size(){
            let items_ = items.get(this);
            return Object.keys(items_).length;
        }
        values(){
            let values = [];
            let items_ = items.get(this);
            for (let i=0, keys=Object.keys(items_); i<keys.length; i++) {
                values.push(items_[keys[i]]);
            }
            return values;
        }
        getItems(){
            return items.get(this);
        }
        union(otherSet){
            let unionSet = new Set();
            let values = this.values();
            for (let i=0; i<values.length; i++){
                unionSet.add(values[i]);
            }
            values = otherSet.values();
            for (let i=0; i<values.length; i++){
                unionSet.add(values[i]);
            }
            return unionSet;
        }
        intersection(otherSet){
            let intersectionSet = new Set();
            let values = this.values();
            for (let i=0; i<values.length; i++){
                if (otherSet.has(values[i])){
                    intersectionSet.add(values[i]);
                }
            }
            return intersectionSet;
        }
        difference(otherSet){
            let differenceSet = new Set();
            let values = this.values();
            for (let i=0; i<values.length; i++){
                if (!otherSet.has(values[i])){
                    differenceSet.add(values[i]);
                }
            }
            return differenceSet;
        };
        subset(otherSet){
            if (this.size() > otherSet.size()){
                return false;
            } else {
                let values = this.values();
                for (let i=0; i<values.length; i++){
                    if (!otherSet.has(values[i])){
                        return false;
                    }
                }
                return true;
            }
        };
    }
    return Set2;
})();

  

本文由职坐标整理发布,欢迎关注职坐标WEB前端JavaScript频道,获取更多JavaScript知识!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程