Map 与 Set 数据类型

412 阅读5分钟

Map

基本概念

对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。

let myMap = new Map()

let kvArray = [['key1', 'value1'], ['key2', 'value2']];
let myMap = new Map(kvArray); 

初始值可以为数组或 iterable

Map 和 Object 的区别

1.Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
2.Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
3.Map 上键值对的键名可以使用任意值,但 Object 的键名只能使用字符串或 Symbols 类型。
4.Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。

属性

Map.prototype.size

size 是可访问属性,用于返回一个 Map 对象的成员数量。

let kvArray = [['key1', 'value1'], ['key2', 'value2']];
let myMap = new Map(kvArray); 

console.log(myMap.size)                    // 2

方法

Map.prototype.clear()

移除 Map 对象中的所有元素。

let kvArray = [['key1', 'value1'], ['key2', 'value2']];
let myMap = new Map(kvArray); 

myMap.clear();

console.log(myMap.size)                    // 0

Map.prototype.delete()

用于移除 Map 对象中指定的元素。

let kvArray = [['key1', 'value1'], ['key2', 'value2']];
let myMap = new Map(kvArray); 

myMap.delete('key1');

console.log(myMap)                         // Map {'key2' => 'value2'}

Map.prototype.entries()

返回一个新的包含 [key, value] 对的 iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同。

let kvArray = [['key1', 'value1'], ['key2', 'value2']];
let myMap = new Map(kvArray); 

const iterator = myMap.entries();

console.log(iterator)                      // MapIterator {'key1' => 'value1', 'key2' => 'value2'}
console.log(myMap)                         // Map {'key1' => 'value1', 'key2' => 'value2'}

Map.prototype.forEach()

以插入顺序对 Map 对象中的每一个键值对执行一次参数中提供的回调函数。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);

function logMap(value, key, map) {
  console.log('m[' + key '] = ' + value);
}

map.forEach(logMap)
// m[foo] = 3
// m[bar] = [object Object]
// m[baz] = undefined

Map.prototype.get()

返回某个 Map 对象中的一个指定元素。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);

map.get('bar')                             // {}

Map.prototype.has()

返回一个 bool 值,判断 map 中是否存在指定元素。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);

map.has('bar');                            // true
map.has('hat');                            // false

Map.prototype.keys()

返回一个 iterator 对象。包含按照顺序插入 Map 对象中每个元素的 key 值。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);
var iterator = map.keys();

console.log(iterator)                      // MapIterator {'foo', 'bar', 'baz'}

Map.prototype.set()

为 Map 对象添加或更新一个指定了键(key)和值(value)的(新)键值对。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);
console.log(map);                          // {'foo' => 3, 'bar' => {}, 'baz' => undefined}

map.set('bas', 'value');
console.log(map);                          // {'foo' => 3, 'bar' => {}, 'baz' => undefined, 'bas' => value}

map.set('bas', 'value2');
console.log(map);                          // {'foo' => 3, 'bar' => {}, 'baz' => undefined, 'bas' => value2}

Map.prototype.values()

返回一个新的 iterator 对象。它包含按顺序插入 Map 对象中每个元素的 value 值。

var map = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);

console.log(map)                           // MapIterator {3, {...}, undefined}

Map 适用

1.键名需要是除 Symbols 和字符串类型以外的数据类型。

2.相比较数组具有更快的查找速度

数组需要查询学生对应的成绩时,需要两个数组

var names = ['Michael', 'Bob', 'Tracy']; var scrores = [95, 75, 85];

先查到名字对应的 index,使用 index 找到成绩

Map 的话,直接根据名字查成绩即可,无论表多大,都不会影响速度

Set

基本概念

对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

const mySet = new Set([1, 2, 3, 4, 5])

所有元素不重复的添加到新的 Set 中。

Set 特殊值

1.+0 和 -0 在存储判断唯一性的时候是恒等的,所有两者不存在同时存在的情况。 2.undefined 和 undefined 是恒等的。 3.NaN 和 NaN 是不恒等的,但 Set 中认为是相等的。

属性

Set.prototype.size()

将返回 Set 对象中元素的个数。

var mySet = new Set([[4, 3], ['bar', {}], ['baz', undefined]]);

console.log(mySet.size);                   // 3

方法

Set.prototype.add()

向一个 Set 对象的末尾添加一个指定的值。

var mySet = new Set([4, 'bar', 'baz']);
mySet.add(5);

console.log(mySet)                         // Set {4, 'bar', 'baz', 5}

Set.prototype.clear()

清空一个 Set 对象中的所有元素。

var mySet = new Set([4, 'bar', 'baz']);
mySet.clear();

console.log(mySet)                         // Set {}

Set.prototype.delete()

从一个 Set 对象中删除指定的元素。

var mySet = new Set([4, 'bar', 'baz']);
mySet.delete('bar');

console.log(mySet)                         // Set {4, 'baz'}

Set.prototype.entries()

返回一个新的迭代器对象,这个对象的元素类似 [value, value] 形式的数组,value 是集合对象中的每个元素,迭代器对象的顺序。由于集合对象不像 Map 对象那样拥有 key,然而,为了与 Map 对象的 API 形式保持一致,故使得每一个 entry 的 key 和 value 都拥有相同的值,因而最终返回一个 [value, value] 形式的数组。

var mySet = new Set([4, 'bar', 'baz']);
const myIterator = mySet.entries();

console.log(myIterator)                    // SetInterator {4 => 4, 'bar' => 'bar' , 'baz' => 'baz' }

Set.prototype.forEach()

根据集合中元素的插入顺序,依次执行提供的回调函数。

var mySet = new Set([4, 'bar', 'baz']);
function logSet(value1, value2, set) {
  console.log('s[' + value1 + '] = ' + value2);
}

mySet.forEach(logSet)
// 's[4] = 4'
// 's[bar] = bar'
// 's[baz] = baz'

Set.prototype.has()

返回 bool 值来判断对应的值 value 是否存在 Set 对象中。

var mySet = new Set([4, 'bar', 'baz']);

mySet.has('bar')                           // true
mySet.has('ba')                            // false

Set.prototype.values()

返回一个 Iterator 对象,该对象按照 Set 对象元素的插入顺序返回其所有元素。

var mySet = new Set([4, 'bar', 'baz']);
const myIterator = mySet.values();

console.log(myIterator)                    // SetInterator {4, 'bar', 'baz'}

Set 适用

1.用于数组去重,但对象数组无法去重,认为两个对象是不一样的。

[...new Set([1, 2, 3, 4, 4, 4])];          // [1, 2, 3, 4]

Array.from(new Set([1, 2, 3, 4, 4, 4]));   // [1, 2, 3, 4]

2.遍历和过滤

let a = new Set([1, 2, 3, 4]);

let b = new Set([...a].map(x => x * 2));
// b => Set(4) {2, 4, 6, 8}

let c = new Set([...a].filter(x => (x % 2) == 0));
// b => Set(2) {2, 4}

3.获取并集、交集和差集

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

let c1 = new Set([...a, ...b]);
// Set [1, 2, 3, 4]

let c2 = new Set([...a].filter(x => b.has(x)));
// Set {2, 3}

let c3 = new Set([...a].filter(x => !b.has(x)));
// Set {1}