JavaScript 3.7 Map 、Set

一、Map

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

Map与Object区别:

Map默认情况不包含任何键。只包含显式插入的键。

Map的键可以是任意值,包括函数、对象或任意基本类型。NaN也可以作为键

Map中的key是有序的。因此,当迭代的时候,一个Map对象以插入的顺序返回键值。

Map的键值对个数可以轻易地通过Size属性获取

Map是 iterable的,所以可以直接被迭代。

Map在频繁增删键值对的场景下表现更好。

一个Object有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。

一个Object的键必须是一个String或是Symbol。

Object 的键值对个数只能手动计算

1、示例
let myMap = new Map();
 
let keyObj = {};
let keyFunc = function() {};
let keyString = 'a string';
 
// 添加键
myMap.set(keyString, "和键'a string'关联的值");
myMap.set(keyObj, "和键keyObj关联的值");
myMap.set(keyFunc, "和键keyFunc关联的值");
 
myMap.size; // 3
 
// 读取值
myMap.get(keyString);    // "和键'a string'关联的值"
myMap.get(keyObj);       // "和键keyObj关联的值"
myMap.get(keyFunc);      // "和键keyFunc关联的值"
 
myMap.get('a string');   
outpit:
"和键'a string'关联的值"
因为keyString === 'a string'

myMap.get({});           
output:
undefined, 因为keyObj !== {}

myMap.get(function() {});
output:
undefined, 因为keyFunc !== function () {}


2、常用方法

myMap.clear()
移除Map对象的所有键/值对 。

myMap.delete(key)
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。
随后调用 myMap.has(key) 将返回 false 。

myMap.entries()
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。

myMap.forEach(callbackFn[, thisArg])
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。
如果为forEach提供了thisArg,它将在每次回调中作为this值。

myMap.get(key)
返回键对应的值,如果不存在,则返回undefined。

myMap.has(key)
返回一个布尔值,表示Map实例是否包含键对应的值。

myMap.keys()
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的键 。

myMap.set(key, value)
设置Map对象中键的值。返回该Map对象。

myMap.values()
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值 。

myMap[@@iterator]()
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。

示例
forEach方法按照插入顺序依次对 Map 中每个键/值对执行一次给定的函数
myMap.forEach(callback(value,key,map), thisArg)
thisAgr可以通过传参,改变this指向,如下

let keyString = 'a string';
 
myMap.set(keyString, "和键'a string'关联的值");
myMap.set(keyObj, "和键keyObj关联的值");
myMap.set(keyFunc, "和键keyFunc关联的值");
var z = new Map();
z.set(1,"test1");
myMap.forEach(function(value,key){
  	console.log(this.get(1));
       }
              ,z);//thisArg传参为z

output:
test1
test1
test1

3、Map和数组的关系
let kvArray = [["key1", "value1"], ["key2", "value2"]];
使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象
let myMap = new Map(kvArray);

myMap.get("key1"); // 返回值为 "value1"

使用Array.from函数可以将一个Map对象转换成一个二维键值对数组
console.log(Array.from(myMap)); // 输出和kvArray相同的数组

更简洁的方法来做如上同样的事情,使用展开运算符
console.log([...myMap]);

或者在键或者值的迭代器上使用Array.from,进而得到只含有键或者值的数组
console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]

4、复制和合并
let original = new Map([
  [1, 'one']
]);

let clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false. 浅比较 不为同一个对象的引用

对象间的合并
let first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

let second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

合并两个Map对象时,如果有重复的键值,则后面的会覆盖前面的。
展开运算符本质上是将Map对象转换成数组。
let merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

和数组的合并
let first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

let second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);
 Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
let merged = new Map([...first, ...second, [1, 'eins']]);

console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

二、Set

对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。et中的元素只会出现一次,即 Set 中的元素是唯一的。

1、常用方法

set的常用方法大部分是和map相似的
set添加元素是用add,mao则用set

let mySet = new Set();
mySet.add("1");
mySet.add(5);

for (let [key, value] of mySet.entries()) 
console.log(key);
为了使这个方法和Map对象保持相似, 每个值的键和值相等

2、基本集合操作
function isSuperset(set, subset) {
    for (let elem of subset) {
        if (!set.has(elem)) {
            return false;
        }
    }
    return true;
}

function union(setA, setB) {
    let _union = new Set(setA);
    for (let elem of setB) {
        _union.add(elem);
    }
    return _union;
}

function intersection(setA, setB) {
    let _intersection = new Set();
    for (let elem of setB) {
        if (setA.has(elem)) {
            _intersection.add(elem);
        }
    }
    return _intersection;
}

function symmetricDifference(setA, setB) {
    let _difference = new Set(setA);
    for (let elem of setB) {
        if (_difference.has(elem)) {
            _difference.delete(elem);
        } else {
            _difference.add(elem);
        }
    }
    return _difference;
}

function difference(setA, setB) {
    let _difference = new Set(setA);
    for (let elem of setB) {
        _difference.delete(elem);
    }
    return _difference;
}

//Examples
let setA = new Set([1, 2, 3, 4]),
    setB = new Set([2, 3]),
    setC = new Set([3, 4, 5, 6]);

isSuperset(setA, setB);          // => true
union(setA, setC);               // => Set [1, 2, 3, 4, 5, 6]
intersection(setA, setC);        // => Set [3, 4]
symmetricDifference(setA, setC); // => Set [1, 2, 5, 6]
difference(setA, setC);          // => Set [1, 2]

3、数组去重
const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)]) 
// [2, 3, 4, 5, 6, 7, 32]

4、String转set
let text = 'India';
let mySet = new Set(text);  // Set {'I', 'n', 'd', 'i', 'a'}
mySet.size;  // 5
大小写敏感
new Set("Firefox")  // Set(7) [ "F", "i", "r", "e", "f", "o", "x" ]
如果是小写firefox,第二个f将会被去重掉

Array参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

Set参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set

Map参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值