Map与Set
Map(映射)
Map 表示映射,是一组键值对的数据集合,类似于对象。对象中的键必须是字符串,且对象的键是无序的;而 Map 的键可以是任意数据类型,且按照插入顺序排序。
创建 Map 对象
通过 Map() 构造函数创建一个 Map 对象,Map() 函数还可以接收 Array 作为参数
let map1 = new Map();
console.log(map1); // Map(0) {size: 0}
let gen = {gender: 'female'};
let map2 = new Map([['name', 'Taylor'], [1, 33], [gen, true]]);
console.log(map2); // Map(3) {'name' => 'Taylor', 1 => 33, {gender: 'female'} => true}
使用 typeof 检测 Map 对象的类型结果是 object,而利用 instanceof 检测能得到结果是 Map
let map = new Map();
console.log(typeof Map); // object
console.log(map instanceof Map); // true
Map 属性与方法
属性/方法 | 含义 | 返回值 |
---|---|---|
size属性 | 计算 Map 中元素个数 | \ |
get(key) | 获取 Map 对象中指定键的值 | 键名存在则返回对应的值,否则返回 undefined |
set(key, value) | 为 Map 对象中的键设置值 | 返回设置后的 Map 对象 |
has(key) | 判断 Map 对象中是否存在指定键 | 存在则返回 true,否则返回 false |
entries() | 获取 Map 对象中所有键值对 | 返回一个由 Map 中所有键值对组成的 Iterator 对象,迭代顺序按照 Map 中的顺序 |
keys() | 获取 Map 对象中所有元素的键名 | 返回一个由 Map 中所有键名组成的 Iterator 对象,迭代顺序按照 Map中的顺序 |
values() | 获取 Map 对象中所有元素的值 | 返回一个由 Map 中所有的值组成的 Iterator 对象,迭代顺序按照 Map 中的顺序 |
forEach(callback) | 根据 Map 中元素的顺序,对每个键值对都执行一次 callback 函数 | 无返回值 |
delete(key) | 删除 Map 对象中指定键对应的元素 | 键存在则将其删除并返回 true,否则返回 false |
clear() | 清空 Map 对象 | 无返回值 |
通过 size 属性可以获取 Map 对象中元素的个数
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.size); // 3
get(key) 方法可以获取 Map 对象中指定键对应的值
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.get(1)); // 1
set(key, value) 方法设置 Map 对象中的键值对,可以进行添加或者修改操作
let obj = {name: 'Taylor'};
let map = new Map();
console.log(map.set(obj, '1')); // Map(1) {{name: 'Taylor} => '1'}
console.log(map.get(obj)); // 1
console.log(map.set(obj, '2')); // Map(1) {{name: 'Taylor} => '2'}
console.log(map.get(obj)); // 2
has(key) 方法判断指定键是否存在于 Map 对象中,存在则返回 true,否则返回 false
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.has(1)); // true
entries() 方法获取 Map 对象中所有键值对,返回一个由所有键值对按插入顺序组成的 Iterator 对象
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.entries()); // MapIterator {1 => '1', 2 => '2', 3 => '3'}
keys() 方法获取 Map 对象中所有键值对的键名,返回一个由所有键名按插入顺序组成的 Iterator 对象
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.keys()); // MapIterator {1, 2, 3}
values() 方法获取 Map 对象中所有键值对的值,返回一个由所有值按插入顺序组成的 Iterator 对象
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.values()); // MapIterator {'1', '2', '3'}
forEach(callback([value][,key][,map])[, thisArg]) 方法遍历 Map 对象中每一个键值对,并对每个真实存在的键值对都执行一次 callback 函数
callback 接收三个参数:value(当前键值对的值)、key(当前键值对的键名)、map(正在遍历的Map对象)
let map = new Map([['name', 'Taylor'], [2, '33'], [true, 'singer']]);
map.forEach(function(value, key, self){
console.log("now key="+key+", value="+value);
});
// now key=name, value=Taylor
// now key=2, value=33
// now key=true, value=singer
delete(key) 方法删除 Map 对象中指定键对应的元素,若指定键存在则将元素删除并返回 true,否则返回 false
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.delete(1)); // true
console.log(map.delete(1)); // flase
console.log(map); // Map(2) {2 => '2', 3 => '3'}
clear() 方法清空 Map 对象
let map = new Map([[1, '1'], [2, '2'], [3, '3']]);
console.log(map.clear()); // undefined
console.log(map); // Map(0) {size:0}
Map 与其它数据类型相互转换
Map 与数组相互转换
Map 转换成数组,可以利用 Array.from() 方法或者扩展运算符,得到的是一个二维数组
let map = new Map();
map.set(1,'aaa').set(2,'bbb').set(3,'ccc');
console.log(map); // Map(3) {1 => 'aaa', 2 => 'bbb', 3 => 'ccc'}
let arr = [...map];
console.log(arr); // [[1, 'aaa'], [2, 'bbb'], [3, 'ccc']]
数组转换成 Map,可以将数组作为参数传给 Map 构造函数,注意必须是一个二维数组
let arr = ['a', 1, 'b', 2];
let map = new Map(arr); // 报错
let gen = {gender: 'female'};
let map2 = new Map([['name', 'Taylor'], [1, 33], [gen, true]]);
console.log(map2); // Map(3) {'name' => 'Taylor', 1 => 33, {gender: 'female'} => true}
Map 与对象相互转换
Map 转换成对象,利用 for…of 遍历 Map 对象,将键值对拆解存入对象中
let map = new Map();
map.set(1,'aaa').set(2,'bbb').set(3,'ccc');
console.log(map); // Map(3) {1 => 'aaa', 2 => 'bbb', 3 => 'ccc'}
let obj = {};
for(let [k, v] of map) {
obj[k] = v;
}
console.log(obj); // {1: 'aaa', 2: 'bbb', 3: 'ccc'}
对象转换成 Map,利用 for…in 遍历对象,然后利用 set() 方法将属性名和属性值存入 Map 中
let obj = {
name: 'Taylor',
age: 33,
job: 'singer'
};
let map = new Map();
for (let k in obj) {
map.set(k, obj[k]);
}
console.log(map); // Map(3) {'name' => 'Taylor', 'age' => 33, 'job' => 'singer'}
Map 与 JSON 数据相互转换
Map 转换成 JSON 格式的数据,可以利用转对象的方法 + JSON.stringify()
let map = new Map();
map.set(1,'aaa').set(2,'bbb').set(3,'ccc');
console.log(map); // Map(3) {1 => 'aaa', 2 => 'bbb', 3 => 'ccc'}
let obj = {};
for(let [k, v] of map) {
obj[k] = v;
}
let json = JSON.stringify(obj);
console.log(json); // {"1": "aaa", "2": "bbb", "3": "ccc"}
JSON 格式的数据转换成 Map,可以利用 JSON.parse() + 对象转 Map 的方法
let json = '{"name": "Taylor","age": 33,"gender": "female","job": "singer"}';
let obj = JSON.parse(json);
console.log(obj); // {name: 'Taylor', age: 33, gender: 'female', job: 'singer'}
let map = new Map();
for (let k in obj) {
map.set(k, obj[k]);
}
console.log(map);
// Map(4) {'name' => 'Taylor', 'age' => 33, 'gender' => 'female', 'job' => 'singer'}
Set(集合)
Set 表示集合,是一组唯一值的数据集合,类似于数组。但 Set 中的元素都是唯一的,不存在相同的元素,可以利用它进行数组去重;且Set对象的值可以是任意数据类型
创建 Set 对象
通过 Set() 构造函数创建一个 Set 对象,Set() 函数还可以接收 Array 作为参数
let set1 = new Set();
console.log(set1); // Map(0) {size: 0}
let gen = {gender: 'female'};
let gen1 = gen;
let set2 = new Set([['name', 'Taylor'], [1, 33], [gen, true]]);
console.log(set2); // Set(3) {'name' => 'Taylor', 1 => 33, {gender: 'female'} => true}
使用 typeof 检测 Set 对象的类型结果是 object,而利用 instanceof 检测能得到结果是 Set
let set = new Set();
console.log(typeof set); // object
console.log(set instanceof Set); // true
Set 的属性与方法
属性/方法 | 含义 | 返回值 |
---|---|---|
size属性 | 计算 Set 中元素个数 | \ |
add(value) | 向 Set 对象中添加元素 | 返回设置后的 Set 对象 |
has(value) | 判断 Set 对象中是否存在指定值 | 存在则返回 true,否则返回 false |
entries() | 获取 Set 对象中所有元素的值 | 返回一个由 Set 对象中所有值组成的 Iterator 对象,迭代顺序按照 Set 中的顺序 |
keys() | 获取 Set 对象中所有元素的值 | 返回一个由 Set 对象中所有值组成的 Iterator 对象, 迭代顺序按照 Set 中的顺序 |
values() | 获取 Set 对象中所有元素的值 | 返回一个由 Set 对象中所有值组成的 Iterator 对象, 迭代顺序按照 Set 中的顺序 |
forEach(callback) | 根据 Set 中元素的顺序,对每个元素都执行一次 callback 函数 | 无返回值 |
delete(value) | 删除 Set 对象中指定值对应的元素 | 存在则将其删除并返回 true,否则返回 false |
clear() | 清空 Set 对象 | 无返回值 |
通过 size 属性能获取 Set 对象中元素个数
let set = new Set(['a','b','c']);
console.log(set.size); // 3
add(value) 方法向 Set 对象中添加元素并返回 Set 对象
let set = new Set(['a','b','c']);
console.log(set.add('d')); // Set(4) {'a', 'b', 'c', 'd'}
console.log(set.add('a')); // 添加重复元素无效
has(value) 方法判断指定值是否存在于 Set 对象中,存在则返回true,否则返回false
let set = new Set(['a','b','c']);
console.log(set.has('a')); // true
console.log(set.has(1)); // false
entries()、keys()、values() 方法都返回一个由 Set 对象中所有值组成的 iterator 迭代器
entries() 本应该返回的是键名与键值一 一对应的迭代器,但是 Set 对象中没有键名,或者说键名就是元素值,所以返回的迭代器中都是元素值
let set = new Set(['a','b','c']);
console.log(set2.entries());
// SetIterator {'a' => 'a', 'b' => 'b', 'c' => 'c'}
console.log(set2.keys());
// SetIterator {'a', 'b', 'c'}
console.log(set2.values());
// SetIterator {'a', 'b', 'c'}
forEach(callback([value1][,value2][,set])[, thisArg]) 方法遍历 Set 对象中每一个元素,并对每个真实存在的元素都执行一次 callback 函数
callback 接收三个参数:value1(当前元素的值)、value2(当前元素的值)、set(正在遍历的 Set 对象)
let set = new Set(['a','b','c']);
set.forEach(function(value1, value2, set){
console.log(`now value1=${value1},value2=${value2}`);
});
// now value1=a,value2=a
// now value1=b,value2=b
// now value1=c,value2=c
delete(value) 方法删除 Set 对象中指定值对应的元素,若指定值存在则将元素删除并返回 true,否则返回 false
let set = new Set(['a','b','c']);
console.log(set.delete('a')); // true
console.log(set.delete('a')); // false
clear() 方法清空 Set 对象
let set = new Set(['a','b','c']);
set.clear();
console.log(set); // Set(0) {size: 0}
Set 与其它数据类型相互转换
Set 与数组相互转换
Set 对象转换成数组,利用 Array.from() 方法或者扩展运算符或者 forEach + Array.push() 方法
let set = new Set(['a','b','c']);
let arr = Array.from(set);
console.log(arr); // ['a', 'b', 'c']
console.log([...set]); // ['a', 'b', 'c']
数组转换成 Set 对象,直接将数组传入 Set 构造函数作为参数
let arr = ['b', 'c', 'd'];
let set = new Set(arr);
console.log(set); // Set(3) {'b', 'c', 'd'}
因为 Set 中不存在重复的元素,可以利用 Set 进行
数组去重
。先将需要去重的数组转换为 Set 对象,然后再将 Set 对象转为数组
let arr = [1, 1, 2, 4, 3, 4, 6, 6];
let set = new Set(arr);
console.log(set); // Set(5) {1, 2, 4, 3, 6}
let arr1 = [...set];
console.log(arr1); // [1, 2, 4, 3, 6]