Checkson / blog

Checkson个人博客
12 stars 3 forks source link

JavaScript 集合 #26

Open Checkson opened 5 years ago

Checkson commented 5 years ago

前言

集合(set)是一种包含不同元素的数据结构。集合中的元素称为成员。集合的两个最重要特性是:

集合在计算机科学中扮演了非常重要的角色,然而在很多编程语言中,并不把集合当成一种数据类型。当你想要创建一个数据结构,用来保存一些独一无二的元素时,比如一段文本中用到的单词,集合就变得非常有用。ES6中已经实现了Set类,那么这里,我们尝试自己去实现一个类似ES6中Set类。

定义

集合是由一组无序但彼此之间又有一定相关性的成员构成的,每个成员在集合中只能出现一次。在数学上,用大括号将一组成员括起来表示集合,比如 {0,1,2,3,4,5,6,7,8,9}。集合中成员的顺序是任意的,因此前面的集合也可以写做 {9,0,8,1,7,2,6,3,5,4},或者其他任意形式的组合,但是必须保证每个成员只能出现一次。

另外,下面是一些使用集合时必须了解的定义:

而对集合的基本操作有下面几种:

集合(Set)类实现

1. 构造函数

完整代码地址

function Set (arr) {
    if (arr && !Array.isArray(arr)) {
        throw new Error('传入的参数是非数组类型!');
    }
    this.dataStore = [];
    if (arr.length) {
        var _this = this;
        arr.forEach(function (item) {
            _this.add(item);
        });
    }
}

2. add:向集合中添加元素

Set.prototype.add = function (data) {
    if (!this.has(data)) {
        this.dataStore.push(data);
        return true;
    }
    return false;    
}

3. has:判断某个元素是否在集合中存在

Set.prototype.has = function (data) {
    return this.dataStore.indexOf(data) > -1;
}

4. remove:删除集合中的某个元素

Set.prototype.remove = function (data) {
    var pos = this.dataStore.indexOf(data);
    if (pos > -1) {
        this.dataStore.splice(pos, 1);
        return true;
    }
    return false;
}

5. clear:清除集合中的所有成员

Set.prototype.clear = function () {
    delete this.dataStore;
    this.dataStore = [];
}

6. size:获取集合中的元素个数

Set.prototype.size = function () {
    return this.dataStore.length;
}

7. show:返回集合中的元素

Set.prototype.show = function () {
    return this.dataStore;
}

8. union:求集合的并集

Set.prototype.union = function (set) {
    var tempSet = new Set();
    this.dataStore.forEach(function (item) {
        tempSet.add(item);
    });
    set.show().forEach(function (item) {
        if (!tempSet.has(item)) {
            tempSet.add(item);
        }
    });
    // 返回集合并集
    return tempSet;
}

9. intersect:求集合的交集

Set.prototype.intersect = function (set) {
    this.dataStore.forEach(function (item) {
        if (set.has(item)) {
            tempSet.add(item);
        }
    });
    return tempSet;
}

10. subSet:判断一个集合是否是另一个集合的子集

Set.prototype.subSet = function (set) {
    if (this.size() > set.size()) {
        return false;
    } 
    this.dataStore.forEach(function (item) {
        if (!set.has(item)) {
            return false;
        }
    });
    return true;
}

11. difference::求集合与另一个集合的补集

Set.prototype.difference = function (set) {
    var tempSet = new Set();
    this.dataStore.forEach(function (item) {
        if (!set.has(item)) {
            tempSet.add(item);
        }
    });
    return tempSet;
};

集合(Set)类测试

var set = new Set([1, 2, 3])
console.log(set.show());
set.remove(3);
console.log(set.show());
set.clear();
console.log(set.show());
var set1 = new Set([1, 2, 3, 4]);
var set2 = new Set([3, 4, 5, 6]);
var unionSet = set1.union(set2);
console.log(unionSet.show());
var intersectSet = set1.intersect(set2);
console.log(intersectSet.show());
console.log(set.subSet(set1));
set.add(1);
set.add(2);
set.add(3);
var diffSet = set.difference(set2);
console.log(diffSet.show());

运行结果:

[ 1, 2, 3 ]
[ 1, 2 ]
[]
[ 1, 2, 3, 4, 5, 6 ]
[ 3, 4 ]
true
[ 1, 2 ]

集合应用

据我所知,集合在生产环境中,大多时候的作用是辅助去重的功能。

参考地址