JavaScript_SA 集合

集合是由一组无序且唯一(即不能重复)的项组成的。
这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。
1、创建集合
在这里我们要实现的集合是以ES6中的Set类的实现为基础的 也就是我们使用对象而不是数组来表示集合 JS的对象不允许一个键指向两个不同的属性 也保证了集合里的元素都是唯一的

let items = {};
function Set() {
}

2、集合的方法:
add添加。
remove delete移除。
has如果值在集合中,返回true,否则返回false。
clear移除集合中的所有项。
size返回集合所包含元素的数量。与数组的length属性类似。
values返回一个包含集合中所有值的数组。
①add

this.add = function (value) {
    if (!this.has(value)) {
        items[value] = value; //{1} 
        return true;
    }
    return false;
};
//或者
this.has = function(value){ 
    return items.hasOwnProperty(value); 
};
let items = {};
function Set() {
    this.has = function (value) {
        return value in items;
    };
    this.add = function (value) {
        if (!this.has(value)) {
            items[value] = value; //{1} 
            return true;
        }
        return false;
    };
}
//调用
let set = new Set();
set.add(1);
set.add(2);
console.log(items); //{1: 1, 2: 2}

②remove

this.remove = function (value) {
if (this.has(value)) {/*验证给定的value是否存在于集合中。
如果存在,就从集合中移除value*/
    delete items[value]; 
    return true;
    }
    return false;
};

③clear 清除

this.clear = function(){ 
     items = {}; // {3} 
};

④size 返回长度

/*使用JavaScript内建的Object类的一个内建函数:JavaScript
的Object类有一个keys方法,它返回一个包含给定对象所有属性
的数组。在这种情况下,可以使用这个数组的length属性来返回
items对象的属性个数。以上代码只能在现代浏览器中运行*/
this.size = function(){ 
    return Object.keys(items).length; 
};
//其他方法
/*手动提取items对象的每一个属性,记录属性的个数并返回这个
数字。这个方法可以在任何浏览器上运行,和之前的代码是等价的*/
this.sizeLegacy = function () {
    let count = 0;
    for (let key in items) { //遍历items对象的所有属性
        if (items.hasOwnProperty(key))//检查它们是否是对象自身的属性 
            ++count;/*如果是,就递增count变量的值,最后在方
    法结束时返回这个数字。*/
    }
    return count;
};

不能简单地使用for-in语句遍历items对象的属性,并递增count变量的值。还需要使用hasOwnProperty方法(以验证items对象具有该属性),因为对象的原型包含了额外的属性(属性既有继承自JavaScript的Object类的,也有属于对象自身,未用于数据结构的)。
⑤values 值

//现代浏览器
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) { //{7} 
        if (items.hasOwnProperty(key)) { //{8} 
            values.push(items[key]);
        }
    }
    return values;
};

3、方法的调用

let items = {};
function Set() {
    this.has = function (value) {
        return value in items;
    };
    this.add = function (value) {
        if (!this.has(value)) {
            items[value] = value;  
            return true;
        }
        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 () {
        let values = [];
        for (let key in items) { 
            if (items.hasOwnProperty(key)) { 
                values.push(items[key]);
            }
        }
        return values;
    };
}
let set = new Set();
set.add(1);
console.log(set.values()); //[1] 
console.log(set.has(1)); //true 
console.log(set.size()); //1
set.add(2);
console.log(set.values()); //[1, 2] 
console.log(set.has(2)); //true 
console.log(set.size()); //2 
set.remove(1);
console.log(set.values()); //[2] 
set.remove(2);
console.log(set.values()); //[]

4、集合的操作
并集
交集
差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集
合的元素的新集合。
子集:验证一个给定集合是否是另一集合的子集。
①并集

this.union = function(otherSet){ 
    let unionSet = new Set();//创建一个新的集合,代表两个集合的并集 
    let values = this.values(); /*接下来,获取第一个集合(当前的
    Set类实例)所有的值(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; 
};
//调用
let setA = new Set(); 
setA.add(1); 
setA.add(2); 
setA.add(3); 
let setB = new Set(); 
setB.add(3); 
setB.add(4); 
setB.add(5); 
setB.add(6); 
let unionAB = setA.union(setB); 
console.log(unionAB.values());//[1, 2, 3, 4, 5, 6]

②交集

this.intersection = function (otherSet) {
    let intersectionSet = new Set(); /*创建
一个新的Set实例,这样就能用它返回共有的元素*/ 
    let values = this.values();
    for (let i = 0; i < values.length; i++) { /**/{2} 
        if (otherSet.has(values[i])) { /*遍历当前Set实例
所有的值(行{2}),验证它们是否也存在于otherSet实例之中*/ 
            intersectionSet.add(values[i]); /*可以用这一章前
面实现的has方法来验证元素是否存在于Set实例中。然后,如果这个值也
存在于另一个Set实例中,就将其添加到创建的intersectionSet变量中*/
        }
    }
    return intersectionSet;
}
//调用
let setA = new Set(); 
setA.add(1); 
setA.add(2); 
setA.add(3); 
let setB = new Set(); 
setB.add(2); 
setB.add(3); 
setB.add(4); 
let intersectionAB = setA.intersection(setB); 
console.log(intersectionAB.values());//[2, 3]

③差集

this.difference = function (otherSet) {
    let differenceSet = new Set(); //{1} 
    let values = this.values();
    for (let i = 0; i < values.length; i++) { //{2} 
        if (!otherSet.has(values[i])) { //{3} 
            differenceSet.add(values[i]); //{4} 
        }
    }
    return differenceSet;
};
//调用
let setA = new Set(); 
setA.add(1); 
setA.add(2); 
setA.add(3); 
let setB = new Set(); 
setB.add(2); 
setB.add(3); 
setB.add(4); 
let differenceAB = setA.difference(setB); 
console.log(differenceAB.values()); //[1]

④子集

this.subset = function (otherSet) {
    if (this.size() > otherSet.size()) { /*首先需要验证的
是当前Set实例的大小。如果当前实例中的元素比otherSet实例更多,
它就不是一个子集。子集的元素个数需要小于或等于要比较的集合。*/
        return false;
    } else {
        let values = this.values();
        for (let i = 0; i < values.length; i++) { /*接下来
        要遍历集合中的所有元素*/
            if (!otherSet.has(values[i])) { /*验证这些元素也
            存在于otherSet中*/
                return false;/*如果有任何元素不存在于otherSet
         中,就意味着它不是一个子集,返回false。如果所有元素都存
         在于otherSet中,该操作就不会被执行,那么就返回true。*/
            }
        }
        return true; //{5} 
    }
};
//调用
let setA = new Set(); 
setA.add(1);
setA.add(2); 
let setB = new Set(); 
setB.add(1); 
setB.add(2); 
setB.add(3); 
let setC = new Set(); 
setC.add(2); 
setC.add(3); 
setC.add(4); 
console.log(setA.subset(setB)); //true A是不是B的子集
console.log(setA.subset(setC)); //false A是不是C的子集
发布了75 篇原创文章 · 获赞 0 · 访问量 3384

猜你喜欢

转载自blog.csdn.net/E_ISOLATE/article/details/102090856