集合是由一組無序且唯一(即不能重複)的項組成的。這個數據結構使用了與有限集合相同的數學概念,但應用在計算機科學的數據結構中。
還有一個概念叫空集。空集就是不包含任何元素的集合。
你也可以把集合想象成一個既沒有重複元素,也沒有順序概念的數組。
沒有順序意味着不能通過下標值進行訪問,不能重複意味着相同的對象在集合中只會存在一份。
在ES6中的Set類就是一個集合類,這裏我們重新封裝一個Set類,瞭解集合的底層實現。
集合常見的操作:
- add(value):向集合添加一個新的項;
- remove(value):從集合中移除一個值;
- has(value):如果值在集合中,返回true,否則返回false;
- clear():移除集合中的所有項;
- size():返回集合所包含元素的數量,與數組的length屬性相似;
- values():返回一個包含集合中所有值的數組;
封裝集合類(對象實現)
有一個非常重要的細節,我們使用對象而不是數組來表示集合(items)。但也可以用數組實現。在這裏我們用對象來實現,稍微有點兒不一樣,也學習一下實現相似數據結構的新方法。
同時,JavaScript的對象不允許一個鍵指向兩個不同的屬性,也保證了集合裏的元素都是唯一的。
//封裝集合類
function Set() {
//屬性
this.items = {}
//方法
//一.has方法
Set.prototype.has = value => {
// 所有JavaScript對象都有hasOwnProperty方法。
// 這個方法返回一個表明對象是否具有特定屬性的布爾值。
return this.items.hasOwnProperty(value)
// return value in items;
}
//二.add方法
Set.prototype.add = value => {
//判斷集合中是否已經包含該元素
if (this.has(value)) {
return false
}
//將元素添加到集合中
// 把它同時作爲鍵和值保存,因爲這樣有利於查找這個值。
this.items[value] = value//表示該屬性鍵和值都爲value
return true//表示添加成功
}
//三.remove方法
Set.prototype.remove = (value) => {
//1.判斷集合中是否包含該元素
if (!this.has(value)) {
return false
}
//2.將元素從屬性中刪除
delete this.items[value]
return true
}
//四.clear方法
Set.prototype.clear = () => {
//原來的對象沒有引用指向,會被自動回收
this.items = {}
}
//五.size方法
Set.prototype.size = () => {
return Object.keys(this.items).length
}
//獲取集合中所有的值,以數組形式返回
//六.values方法
Set.prototype.values = function() {
return Object.keys(this.items)
}
}
並集:對於給定的兩個集合,返回一個包含兩個集合中所有元素的新集合;
交集:對於給定的兩個集合,返回一個包含兩個集合中共有元素的新集合;
差集:對於給定的兩個集合,返回一個包含所有存在於第一個集合且不存在於第二個集合的元素的新集合;
子集:驗證一個給定集合是否是另一個集合的子集;
並集的實現
Set.prototype.union = otherSet => {
// this:集合對象A
// otherSet:集合對象B
//1.創建一個新的集合
let unionSet = new Set()
//2.將A集合中的所有元素添加到新集合中
let values = this.values()
for(let i = 0;i < values.length;i++){
unionSet.add(values[i])
}
//3.取出B集合中的元素,判斷是否需要加到新集合中
values = otherSet.values()
for(let i = 0;i < values.length;i++){
unionSet.add(values[i])
}
return unionSet
}
交集的實現
Set.prototype.intersection = otherSet => {
// this:集合A
// otherSet:集合B
//1.創建新的集合
let intersectionSet = new Set()
//2.從A中取出一個元素,判斷是否同時存在於集合B中,是則放入新集合中
let values = this.values()
for(let i =0 ; i < values.length; i++){
let item = values[i]
if (otherSet.has(item)) {
intersectionSet.add(item)
}
}
return intersectionSet
}
差集的實現
Set.prototype.diffrence = otherSet => {
//this:集合A
//otherSet:集合B
//1.創建新的集合
var diffrenceSet = new Set()
//2.取出A集合中的每一個元素,判斷是否同時存在於B中,不存在則添加到新集合中
var values = this.values()
for(var i = 0;i < values.length; i++){
var item = values[i]
if (!otherSet.has(item)) {
diffrenceSet.add(item)
}
}
return diffrenceSet
}
子集的實現
Set.prototype.subset = otherSet => {
//this:集合A
//otherSet:集合B
//遍歷集合A中的所有元素,如果發現,集合A中的元素,在集合B中不存在,那麼放回false,如果遍歷完整個集合A沒有返回false,就返回true
let values = this.values()
for(let i = 0; i < values.length; i++){
let item = values[i]
if(!otherSet.has(item)){
return false
}
}
return true
}
封裝集合類(數組實現)
function Set() {
//屬性
this.dataStore = []
//方法
//一.has方法
Set.prototype.has = value => {
return this.dataStore.indexOf(data) > -1
}
//二.add方法
Set.prototype.add = value => {
//判斷集合中是否已經包含該元素
if (this.dataStore.indexOf(data) < 0) {
this.dataStore.push(data);
return true;
} else {
return false;
}
}
//三.remove方法
Set.prototype.remove = (value) => {
//1.判斷集合中是否包含該元素
var pos = this.dataStore.indexOf(data);
if (pos > -1) {
this.dataStore.splice(pos,1);
return true;
} else {
return false;
}
}
//四.clear方法
Set.prototype.clear = () => {
//原來的對象沒有引用指向,會被自動回收
this.dataStore = []
}
//五.size方法
Set.prototype.size = () => {
return this.dataStore.length
}
//獲取集合中所有的值
//六.values方法
Set.prototype.values = function() {
return this.dataStore
}
}
並集的實現
Set.prototype.union = otherSet => {
// this:集合對象A
// otherSet:集合對象B
//1.創建一個新的集合
let unionSet = new Set()
//2.將A集合中的所有元素添加到新集合中
let values = this.values()
for(let i = 0;i < values.length;i++){
unionSet.add(values[i])
}
//3.取出B集合中的元素,判斷是否需要加到新集合中
values = otherSet.values()
for(let i = 0;i < values.length;i++){
unionSet.add(values[i])
}
return unionSet
}
交集的實現
Set.prototype.intersection = otherSet => {
// this:集合A
// otherSet:集合B
//1.創建新的集合
let intersectionSet = new Set()
//2.從A中取出一個元素,判斷是否同時存在於集合B中,是則放入新集合中
let values = this.values()
for(let i =0 ; i < values.length; i++){
let item = values[i]
if (otherSet.has(item)) {
intersectionSet.add(item)
}
}
return intersectionSet
}
差集的實現
Set.prototype.diffrence = otherSet => {
//this:集合A
//otherSet:集合B
//1.創建新的集合
var diffrenceSet = new Set()
//2.取出A集合中的每一個元素,判斷是否同時存在於B中,不存在則添加到新集合中
var values = this.values()
for(var i = 0;i < values.length; i++){
var item = values[i]
if (!otherSet.has(item)) {
diffrenceSet.add(item)
}
}
return diffrenceSet
}
子集的實現
Set.prototype.subset = otherSet => {
//this:集合A
//otherSet:集合B
//遍歷集合A中的所有元素,如果發現,集合A中的元素,在集合B中不存在,那麼放回false,如果遍歷完整個集合A沒有返回false,就返回true
let values = this.values()
for(let i = 0; i < values.length; i++){
let item = values[i]
if(!otherSet.has(item)){
return false
}
}
return true
}