读书笔记-JavaScript实现「集合」

目标

  • 学习如何创建集合,添加、移除值、搜索是否存在
  • 学习如何做并集、交集、差集的数据操作
  • 学习如何使用 ES6 的 Set 类

集合是无顺序、不重复的的项组成的数据结构。与数学中的有限集合是通过一个概念

ES6 原生的 Set 就是「集合」,原生的 Map 就是「字典」

6.2 实现与 ES6 的 Set 相似的一个集合结构

function Set() {
    let items = {};

    this.has = function(value) {
        // 根据in操作符不同,hasOwenProperty只检测自有属性,忽略原型链
        return items.hasOwnProperty(value);
    };

    this.add = function(value) {
        if (!this.has(value)) {
            items[value] = value;
            return true;
        } else {
            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() {
        return Object.values(items);
    };

    // 并集操作
    this.union = function(otherSet) {
        let unionSet = new Set();
        this.values().forEach(value => {
            unionSet.add(value);
        });

        // 因为add时,会用has判断,是否重复的元素不再push
        otherSet.values().forEach(value => {
            unionSet.add(value);
        });
        return unionSet;
    };

    // 交集操作
    this.intersection = function(otherSet) {
        let intersectionSet = new Set();
        this.values().forEach(value => {
            if (otherSet.has(value)) {
                unionSet.add(value);
            }
        });
        return intersectionSet;
    };

    // 判断A是否是B的子集
    this.subset = function(otherSet) {
        return this.values().every(value => {
            return otherSet.has(value);
        });
    };
}

试一试,代码能否正常运行

let set = new Set();
set.add(1);
console.log(set.values());
console.log(set.has(1));
console.log(set.size());
set.add(2);
console.log(set.values());
console.log(set.has(2));
console.log(set.size());

set.remove(1);
console.log(set.values());
set.remove(2);
console.log(set.values());

拓展集合操作 并集、交集、差集

并集操作
// 并集操作
this.union = function(otherSet) {
    let unionSet = new Set();
    this.values().forEach(value => {
        unionSet.add(value);
    });

    // 因为add时,会用has判断,是否重复的元素不再push
    otherSet.values().forEach(value => {
        unionSet.add(value);
    });
    return unionSet;
};

试一试,代码做了并集操作

let set1 = new Set();
set1.add(1);
let set2 = new Set();
set1.add(2);

console.log(set1.union(set2).values());
交集操作
this.intersection = function(otherSet) {
    let intersectionSet = new Set();
    this.values().forEach(value => {
        if (otherSet.has(value)) {
            unionSet.add(value);
        }
    });
    return intersectionSet;
};

试一试,是否实现了交集操作

let set1 = new Set();
set1.add(1);
set1.add(2);
let set2 = new Set();
set2.add(2);

console.log(set1.values());
console.log(set2.values());
console.log(set1.intersection(set2).values());
差集操作
// 差集
this.difference = function(otherSet) {
    let differenceSet = new Set();
    this.values().forEach(value => {
        if (!otherSet.has(value)) {
            differenceSet.add(value);
        }
    });
    return differenceSet;
};

试一试,是否实现了差集操作

let set1 = new Set();
set1.add(1);
set1.add(2);
let set2 = new Set();
set2.add(2);

console.log(set1.values());
console.log(set2.values());
console.log(set1.difference(set2).values());
判断是否是子集的操作
// 判断是否是子集的操作
this.subset = function(otherSet) {
    return this.values().every(value => {
        return otherSet.has(value);
    });
};

试一试,是否实现了判断子集操作

let set1 = new Set();
set1.add(1);
let set2 = new Set();
set2.add(1);
set2.add(2);

console.log(set1.values());
console.log(set2.values());
console.log(set1.subset(set2));

Ziwei
4.1k 声望420 粉丝

前端程序员