Map和Set

Map

Map对象是键值对的集合,和对象一样,键名是唯一的。

Map和Object的比较

MapObject
键的类型可以是任意值,包括函数,对象等。只能是String或者Symbol
size可以直接通过size属性获取需要遍历对象手动计算
迭代可以使用for…of和for…in等方法进行迭代只能使用for…in进行迭代

给map设置属性,不能像给对象一样添加属性。否则设置的值不会存储在Map中

const myMap = new Map();
myMap.name = 'lisi'
console.log(myMap.has('name'));
// false

我们需要使用set(key,value)方法设置属性和值

const myMap = new Map();
myMap.set('name','lisi')
console.log(myMap.has('name'));
// true

同理,获取值时,不能直接通过“.属性名”的方式获取,需要使用get方法。

const myMap = new Map();
myMap.set('name', 'lisi')
console.log(myMap.name);
// undefined
console.log(myMap.get('name'));

如果给同一个键设置值,将会覆盖原来的键值

const myMap = new Map();
myMap.set('name', 'lisi')
myMap.set('name', 'zhangshan')
console.log(myMap.get('name'));
// zhangshan

值得注意的是,在js的语法中,NaN与任何值包括NaN都不相等,但作为Map的键名,NaN和NaN是相等的。

const myMap = new Map();
myMap.set(NaN, 'lisi')
myMap.set(NaN, 'zhangshan')
console.log(myMap.size,myMap.get(NaN));
// 1 'zhangshan'

Map集合既可以使用for…of…循环遍历,也可以使用forEach遍历

const myMap = new Map();
myMap.set('name', 'lisi')
myMap.set('age', 18)
myMap.set('sex', '男')
for (let [key, value] of myMap) {
  console.log(key, value);
}
// name lisi
// age 18
// sex 男
myMap.forEach((value, key) => {
  console.log(key, value);
})
// name lisi
// age 18
// sex 男

如果只是单纯想要获取Map中的键或值,使用keys方法和values方法会更简便,这两种方法都会返回一个map迭代器,再使用Array.from或扩展运算符即可转为数组。

const myMap = new Map();
myMap.set('name', 'lisi')
myMap.set('age', 18)
myMap.set('sex', '男')
console.log(Array.from(myMap.keys()));
// ['name', 'age', 'sex']
console.log([...myMap.values()]);
// ['lisi', 18, '男']

使用Map的构造函数,可以将一个二维的键值对数组转化为Map对象

const arr = [
  ['name', 'lisi'],
  ['age', 14],
  ['sex', '女']
]
const myMap = new Map(arr)
console.log(myMap);
// {'name' => 'lisi', 'age' => 14, 'sex' => '女'}

当然,也可以使用Array.from或扩展运算符将一个Map对象转换为一个二维的键值对数组。

const myMap = new Map();
myMap.set('name', 'lisi')
myMap.set('age', 18)
myMap.set('sex', '男')

console.log(Array.from(myMap) );
console.log([...myMap] );

Set

Set对象是值的集合,而Set集合的元素是唯一的。

方法作用
add(value)向Set对象的尾部添加元素
delete(value)删除值为value的元素,并返回一个布尔值表示是否成功
has(value)判断Set对象是否含有value
clear()清空Set对象中的元素

值得注意的是,在Set中,NaN和NaN被认为是相等的。

const mySet = new Set()
mySet.add(NaN)
mySet.add(NaN)
console.log(mySet.size, mySet);
// 1 {NaN}

使用Set的构造函数,可以将一维数组转化为Set集合

const mySet = new Set([1, true, false, NaN, undefined])
console.log(mySet);
// Set(5) {1, true, false, NaN, undefined}

使用Array.from和扩展运算符,可以将Set集合转换为数组

const mySet = new Set()
mySet.add(1)
mySet.add(true)
mySet.add("dsf")
mySet.add({})
mySet.add(function fn(){})
console.log(Array.from(mySet));
// [1, true, 'dsf', {…}, ƒ]
console.log([...mySet]);
// [1, true, 'dsf', {…}, ƒ]

Set对象可以轻易实现数组去重。

const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]
const mySet = [...new Set(arr)]
console.log(mySet);
// [1, 2, 'abc', true, false, undefined, NaN]

常用来求数组的交并补集,因为数组中可能有重复元素,去重后操作更方便。

求两个数组的交集

const nums1 = [1, 2, 2, 1]
const nums2 = [2, 2]

function intersection(arr1, arr2) {
  const s1 = new Set(arr1)
  const s2 = new Set(arr2)
  return Array.from(s1).filter(item => s2.has(item))
}
console.log(intersection(nums1, nums2));
// [2]

求两个数组的并集

const nums1 = [1, 2, 2, 1]
const nums2 = [2, 3, 4]

function union(arr1, arr2) {
  return Array.from(new Set([...arr1, ...arr2]))
}
console.log(union(nums1, nums2));
// [1, 2, 3, 4]

版权声明:本文为qq_52607834原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。