set结构学习

// 1、数据格式存在意义:类似于数组,但是成员都是唯一的,没有重复值
const s = new Set();
[1, 3, 4, 5, 9, 2, 1, 2, 7, 9].forEach(item => s.add(item));
console.log(s); // Set(7) { 1, 3, 4, 5, 9, 2, 7 }
// 2、add方法向set结构中加入成员,结果表明set结构不会添加重复值

// set函数可以接收一个数组(或者具有 iterable 接口的其他数据结构,类数组)
const ss = new Set([1, 2, 5, 9, 7, 8, 7, 2, 6, 7, 8, 9]);
console.log([...ss]); //[ 1, 2, 5, 9, 7, 8, 6]

// 3、set结构的数据size属性代表的数量多少
console.log(ss.size); // 7

// 4、去重
// 去除数组重复成员
console.log(...new Set([1, 2, 2, 3, 5, 1]));  // 1 2 3 5
//  去除字符串重复部分
console.log(...new Set('asafffgggaafffkk')); //a s f g k
console.log([...new Set('asafffgggaafffkk')].join('')); //asfgk

// 5、set内部判断是否相等用的是"Same-value-zero equality" 类似于===
// 区别在于:set加入值认为NaN等于自身,但是精确运算符认为NaN不等于自身
// 两个对象总是不相等的
let sss = new Set();
let a = NaN;
let b = NaN;
sss.add(a);
sss.add(b);
console.log(sss); // Set(1) { NaN }
console.log(NaN === NaN);  // false
let ssss = new Set();
ssss.add({
    
    });
console.log(ssss.size); // 1
ssss.add({
    
    });
console.log(ssss.size); // 2

console.log('---------------------------------------------');

// Set实例的属性和方法
// 1、原型链
console.log(Set.prototype.constructor.prototype === Set.prototype); // true
console.log(ssss.__proto__ === Set.prototype); // true
// 2、属性:size 返回set实例的成员总数
// 3、add方法,添加某个值,返回的是set本身
console.log(ss.add(10)); // Set(8) { 1, 2, 5, 9, 7, 8, 6, 10 }
// 4、delete删除某个值,返回一个布尔值,标识删除是否成功
console.log(ss.delete(10)); // true
console.log(ss); // Set(7) { 1, 2, 5, 9, 7, 8, 6 }
// 5、has返回一个布尔值,表示改值是否为set的成员
console.log(ss.has(1)); // true
console.log(ss.has(100)); // false
// 6、clear:清除所有成员,没有返回值
console.log(ss.clear());
console.log(ss);  // Set(0) {}
// 7、Array.from方法可以将set结构转换为数组
let s5 = new Set([1, 2, 6, 4, 5, 8, 9, 1, 2, 4]);
console.log(Array.from(s5));  // [ 1, 2, 6, 4, 5, 8, 9]

console.log('-------遍历----------');
// set的遍历操作

// 1、
// set结构的实例有四个方法,可以用于遍历成员
// Set.prototype.keys(); // 返回键名的遍历器
// Set.prototype.values(); // 返回键值的遍历器
// Set.prototype.entries(); // 返回键值对的遍历器
// Set.prototype.forEach(); // 使用回调函数遍历每一个成员

// 注意:Set遍历顺序就是插入顺序,这个特性比较有用,比如使用set保存一个回调函数列表,
// 调用时就可以按照顺序进行调用

// keys方法、value方法,entries方法返回的都是遍历器对象。由于set结构没有键名,只有键值
// (也可以理解为键名键值为同一个值),所以values和keys方法行为应该是完全一致的

let s6 = new Set(['red', 'green', 'blue']);
for (let item of s6.keys()) {
    
    
  console.log(item);
}
// red
// green
// blue
for (let item of s6.values()) {
    
    
  console.log(item);
}
// red
// green
// blue
for (let item of s6.entries()) {
    
    
  console.log(item);
}
// [ 'red', 'red' ]
// [ 'green', 'green' ]
// [ 'blue', 'blue' ]

// set实例默认就可以进行遍历,它的默认遍历器生成函数就是它的values方法
console.log(Set.prototype.values);  // [Function: values]
console.log(Set.prototype[Symbol.iterator] === Set.prototype.values); // true
for (let x of s6) {
    
    
  console.log(x);
}
// red
// green
// blue

// 2、forEach() set结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作没有返回值
let s7 = new Set([1, 2, 2, 3, 4, 6, 4]);
s7.forEach((item, value) => console.log(`${
      
      item}:${
      
      value}:${
      
      typeof item}`));
// 1:1:number
// 2:2:number
// 3:3:number
// 4:4:number
// 6:6:number

// forEach() 方法的参数就是一个处理函数,该函数的参数与数组forEach一致,
// 依次为键值,键名,集合本身,需要注意set结构的键名就是键值,两者是同一个值,因此第一个参数和第二个参数永远都是相等的
// 另外 forEach方法还可以有第二个参数,表示绑定处理函数内部的this对象

// 3、遍历的一些应用
// 扩展运算符(...) 内部使用for...of循环,所以可以用于set结构
let s8 = new Set(['yellow', 'red', 'green']);
console.log(s8); // Set(3) { 'yellow', 'red', 'green' }
console.log([...s8]); // [ 'yellow', 'red', 'green' ]
console.log(Array.isArray([...s8]));  // true   就是数组
// 去重
let s9 = [3, 8, 9, 2, 9, 2, 3];
console.log([...new Set(s9)]); //[ 3, 8, 9, 2 ]
// 我草,数组的map和filter方法也可以间接用于set
let s10 = new Set([2, 4, 8, 2]);
let s10res = new Set([...s10].map(x => x * 2));
console.log(s10res); // Set(3) { 4, 8, 16 }
let s10ress = new Set([...s10].filter(x => x > 7));
console.log(s10ress); // Set(1) { 8 }
// 使用set很容易就可以实现交集,并集,差集
let A = new Set([1, 2, 3]);
let B = new Set([2, 3, 4]);
console.log(new Set([...A, ...B]));  // 并集: Set(4) { 1, 2, 3, 4 }
console.log(new Set([...A].filter(x => B.has(x)))); // 交集:Set(2) { 2, 3 }
console.log(new Set([...A].filter(x => !B.has(x)))); // A相对于B的差集:Set(1) { 1 }

// 如果想在遍历操作中改变原来的set结构,目前是还没有直接的方法,目前有两种变通方法:思想就是set结构可以接收一个数组
// 1、利用原来的set结构映射出一个新的结构,赋值给原来的set结构
// 2、另一种就是Array.from 方法       Array.from方法可以将 Set 结构转为数组。
let s11 = new Set([1, 2, 3]);
s11 = new Set([...s11].map(val => val * 2));
console.log(s11); // Set(3) { 2, 4, 6 }

let s12 = new Set([1, 2, 3]);
s12 = new Set(Array.from(s12, x => x * 4));
console.log(s12); //Set(3) { 4, 8, 12 }

猜你喜欢

转载自blog.csdn.net/weixin_43131046/article/details/125491469
今日推荐