Set集合
定义:
是一种数据的存储结构,不同的场景运用不同的集合存储数据。存放的数据必须为可迭代对象。
作用:
用于存放不重复的数据。
原型方法:
方法和属性 | 含义 |
---|---|
add(value) | 添加某个值,返回Set结构本身 |
delete(value) | 删除某个值,返回一个布尔值,表示删除是否成功 |
has(value) | 返回一个布尔值,表示该值是否为Set的成员 |
clear() | 清除所有成员,没有返回值 |
keys() | 返回键名的遍历器 |
values() | 返回键值的遍历器 |
entries() | 返回键值对的遍历器(for in) |
forEach() | 使用回调函数遍历每个成员 |
size | 获取成员个数 |
实例应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let s=new Set([1,2,2,3,3,4,5,5]);
console.log(s);//[1,2,3,4,5]
s.add(10)
s.add(20)
console.log(s);//[1,2,3,4,5,10,20]
console.log(s.delete(1));//[2,3,4,5,10,20]
console.log( s.has(2));//true
console.log(s.keys());//{2, 3, 4, 5, 10, …}
console.log(s.values());//{2, 3, 4, 5, 10, …}
console.log(s.entries());//{2 => 2, 3 => 3, 4 => 4, 5 => 5, 10 => 10, …}
s.clear()
console.log(s);//{}
</script>
</body>
</html>
简单练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const arr1 = [12,34,55,33,11,33,5,12]
const arr2 = [55,34,11,78,10,19,88,88,99,99]
// 使用set集合完成两个数组的交集、并集和差集
const cross = [...new Set(arr1)].filter(item => arr2.indexOf(item) >= 0)
console.log(cross)
const result = [...new Set([...arr1,...arr2])]
console.log(result)
console.log(result.filter(item => cross.indexOf(item) < 0))
</script>
</body>
</html>
Set源码
class MySet{
constructor(iterator = []){
// 传递的内容必须是一个可迭代对象
if(typeof iterator[Symbol.iterator] !== "function"){
throw new TypeError(`您所提供的${iterator}不是一个可迭代对象`)
}
this._datas = [];
for(const item of iterator){
this.add(item)
}
}
get size(){
return this._datas.length
}
add(data){
if(!this.has(data)){
this._datas.push(data)
}
}
has(data){
for(const item of this._datas){
if(this.isEqual(item,data)){
return true
}
}
return false
}
delete(data){
for(let i = 0 ;i<this._datas.length;i++){
const element = this._datas[i];
if(this.isEqual(element,data)){
this._datas.splice(i,1)
return true
}
}
}
clear(){
this._datas.length = 0
}
*[Symbol.iterator](){
for(const item of this._datas){
yield item;
}
}
forEach(callback){
for(const item of this._datas){
callback(item,item,this)
}
}
// 判断两个数据是否相等
isEqual(data1,data2){
if(data1 == 0 && data2 == 0){
return true
}
return Object.is(data1,data2)
}
}
map集合
定义:
类似于对象,里面保存的数据是键值对的形式但是“键”的范围不限于字符串,各种类型的值( 包括对象)都可以当作键和Object的区别是Map的键名可以为值参数必须是数组,数据项也要为数组
作用:
键名不重复,以键值对的形式存储。
原型方法:
方法和属性 | 含义 |
---|---|
set(key, value) | set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如 果key已经有值,则键值会被更新,否则就新生成该键 |
delete(value) | 删除某个值,返回一个布尔值,表示删除是否成功 |
has(value) | 返回一个布尔值,表示该值是否为Set的成员 |
clear() | 清除所有成员,没有返回值 |
keys() | 返回键名的遍历器 |
values() | 返回键值的遍历器 |
entries() | 返回键值对的遍历器(for in) |
forEach() | 使用回调函数遍历每个成员 |
size | 获取成员个数 |
get(key) | get方法读取key对应的键值,如果找不到key,返回undefined |
实例应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 数组中的子数组里面只能有两项,第一项代表键名,第二项代表键值
const map = new Map([
["a", 1],
[1, 2],
[true, 3]
])
console.log(map)
// 添加属性
map.set("b", 4)
// 取值
console.log(map.get(true))
// 取长度
console.log(map.size)
const map = new Map()
map.set({}, 1)
map.set({}, 2)
let obj = {};
map.set(obj, 1)
map.set(obj, 2)
console.log(map.size)
for (const iterator of map) {
console.log(iterator)
console.log(iterator[0], iterator[1]) //一般不会这么写
}
//for of 遍历可迭代对象
for (const [key, value] of map) {
console.log(key, value)
}
console.log(map);
map.forEach((value, key, map) => {
console.log(value, key, map)
// value 值
// key 键
// map对象本身
})
</script>
</body>
</html>
map源码
class MyMap{
constructor(iterator = []){
if(typeof iterator[Symbol.iterator] !== "function"){
throw TypeError(`您所提供的${iterator}不是一个可迭代对象`)
}
this._datas = [];//
for (const item of iterator) {
if(typeof item[Symbol.iterator] !== "function"){
throw TypeError(`您所提供的${item}不是一个可迭代对象`)
}
// const key = item[0];
// const value = item[1];
const iter = item[Symbol.iterator]();
const key = iter.next().value;//["a",1]
const value = iter.next().value;
this.set(key,value)
}
}
set(key,value){
const obj = this._getObj(key);
if(obj){//如果key值相同则覆盖值
obj.value = value
}else{
this._datas.push({
key,
value
})
}
}
get(key){
const obj = this._getObj(key);
if(obj){
return obj.value
}
return undefined;
}
get size(){
return this._datas.length;
}
delete(key){
for(let i = 0 ;i<this._datas.length;i++){
const element = this._datas[i];
if(this.isEqual(element.key,key)){
this._datas.splice(i,1)
return true
}
}
return false;
}
clear(){
this._datas.length = 0
}
has(key){
return this._getObj(key) !== undefined;
}
*[Symbol.iterator](){
for(const item of this._datas){
yield [item.key,item.value]
}
}
forEach(callback){
for (const item of this._datas) {
callback(item.value,item.key,this)
}
}
_getObj(key){
for(const item of this._datas){
if(this.isEqual(item.key,key)){
return item
}
}
}
isEqual(data1,data2){
if(data1 === 0 && data2 === 0){
return true;
}
return Object.is(data1,data2)
}
}