首页 > 其他分享 >Map数据结构详解

Map数据结构详解

时间:2023-02-21 23:44:10浏览次数:46  
标签:Map set console log 详解 let 数据结构 name

Map

Object本质上是键值对的集合(Hash结构),但Object只能将字符串当做键,这就给Object带来了很大的限制。

let data = {}
let s = {
     name : '东方不败'
 }
data[s] = '西方求败'

// 如果键传入非字符串的值,会自动为字符串
console.log(data);  // {[object Object]: '西方求败'}
console.log(data['[object Object]']);  // 西方求败

为了解决这个问题,es6提供了Map数据结构。它类似于对象,也是键值对集合,但键不局限于字符串,各种类型的值都可以当做键。

  • Object结构:字符串键:值
  • Map结构:值键:值
let data2 = new Map()
let s2 = {
     name : "艺术概论"
}
data2.set(s2,'中国工艺美术史')

console.log(data2.get(s2));  // 中国工艺美术史
console.log(data2);  // key: {name: '艺术概论'} , value : "中国工艺美术史"

在这里插入图片描述
上面案例使用Mapset方法,将s2当做data2的键,使用get方法取值。


Map的一些常用方法

方法 说明
set() 为Map对象添加一个指定键(key)和值(value)的新元素
get() 用来获取Map对象中指定的元素
has() 返回boolean值,用来表明Map中是否存在该元素
delete() 删除对应元素
size 返回Map的成员数
clear() 清除Map所有成员,没有返回值
let data2 = new Map()
let s2 = {
   name : "艺术概论"
 }
data2.set(s2,'中国工艺美术史')

data2.size; // 1
data2.has(s2);  // treu
data2.delete(s2); // true
data2.has(s2); // false
data2.clear(); // undefined

Map参数

Map可以接收数组作为参数,数组的成员是单个单个键值对的数组

let map = new Map([
     ['name','东方不败'],
     ['title','西方求败']
])

console.log(map.size);  // 2
console.log(map);  // {"name" => "东方不败"}, {"title" => "西方求败"}
console.log(map.has('name')); // true
console.log(map.get('name')); // 东方不败

在这里插入图片描述

注意:如果有多个相同的键,后面的键值会覆盖前面的键值

不仅是数组,任何具有Iterator接口、且每个成员都是一个双元素的数组的数据结构,都可以当做Map构造函数的参数,SetMap也可以用来生成新的Map

Set作为参数

let set = new Set([['a',1],['b',2]])
let m = new Map(set)
console.log(m); // {'a' => 1, 'b' => 2}
console.log(m.get('a')); // 1

在这里插入图片描述

Map作为参数

let map2 = new Map([['text','世界现代设计史'],['name','王受之']])
let m2 = new Map(map2)
console.log(m2); // {'text' => '世界现代设计史', 'name' => '王受之'}
console.log(m2.get('text')); // 世界现代设计史
console.log(m2.get('hello')); // 读取不存在的键会返回undefined

在这里插入图片描述

Map只有对同一个对象的引用才视为同一个键

let map3 = new Map()
map3.set(['a',100])
console.log(map3.get(['a'])); // undefined

因为数组不是引用类型,生成多个数组,它们的内存地址是不一样的,其实就是基础数据类型和引用数据类型的应用,这里的两个['a']看似是一样的,其实它们根本就是两个不同的值,Map只有对同一个对象的引用才视为同一个键,没有读取到所以返回undefined。请看下面的例子

let map4 = new Map()
let b = ['b']
let b2 = ['b']
map4.set(b)
console.log(map4.get(b2)); // undefined

Map的值其实是跟内存地址绑定的,内存地址不同,那么键就不同(即使名字一模一样),在这里Map就解决了同名属性冲突的问题,当我们使用别人的库时,使用对象名当做键,就不同担心自己的属性与别人的属性相同了。

如果Map的键是一个简单数据类型的值,如:number、string、boolean,只要这两个值严格相等,Map就视为同一个键,例如:0-0就是同一个键,而布尔值true和字符串true就是不同的键,此外nullundefined也是不同的键。NaN视为同一个键。

let n = new Map()

n.set(0,100)
console.log(n.get(-0)); // 100

n.set(5,123)
console.log(n.get('5'));  // undefined

n.set(true,100)
console.log(n.get(1)); // undefined

n.set(NaN,123)
console.log(n.get(NaN)); // 123

n.set(null,100)
console.log(n.get(null)); // 100
console.log(n.get(undefined)); // undefined

Map遍历方法

Map提供三个遍历器生成函数和一个遍历方法

方法 说明
Map.prototype.keys() 返回键名的遍历器。
Map.prototype.values() 返回键值的遍历器。
Map.prototype.entries() 返回所有成员的遍历器。
Map.prototype.forEach() 遍历 Map 的所有成员。

定义数据

let m3 = new Map([
       ['a',100],
       ['b',200],
       ['c',300]
])

keys

/* keys */
for(let k of m3.keys()){
   console.log(k);  // a  b  c
}

values

/* values */
for(let k of m3.values()){
   console.log(k); // 100  200  300
}

entries

for(let k of m3.entries()){
    console.log(k); // ['a', 100]  ['b', 200]  ['c', 300]
    console.log(k[0],k[1]); // a 100     b 200    c 300
}

// 或

for(let [k,v] of m3.entries()){
   console.log(k,v); // a 100     b 200    c 300
}

forEach

m3.forEach(el => console.log(el))  // 100  200  300
m3.forEach((val,index) => console.log(val,index))  // 100 'a'   200 'b'   300 'c' 

Map数据结构转换

Map转数组

使用扩展运算符将Map结构转换为数组

let a = new Map([
      ['a',1],
      ['b',2],
      ['c',3]
])

console.log([...a.keys()]);  // ['a','b','c']
console.log([...a.values()]); // [1,2,3]
console.log([...a.entries()]); // ['a', 1]  ['b', 2]  ['c', 3]
console.log([...a]); // ['a', 1]  ['b', 2]  ['c', 3]

转换后的数组是一个真正的数组,可以使用数组方法
在这里插入图片描述

let back = [...a].filter((val,index) => val[1] == 2 )
console.log(back); // ['b',2]

数组转Map

let a2 = new Map([
       ['name','东方不败'],
       [{num : 3},['abc']]
])
console.log(a2); // 0: {"name" => "东方不败"}    1: {Object => Array(1)}

在这里插入图片描述


Map转对象

let a3 = new Map()
.set('a',100)
.set('b',200)

/* 通过函数传入map */
function mapToObj(mapVal){
// 在内部创建一个空对象
let obj = {}
// 遍历map结构,给空对象赋值
for([k,v] of mapVal){
      obj[k] = v
  }
    return obj
}
let mObj = mapToObj(a3)
console.log(mObj); // {a: 100, b: 200}

在这里插入图片描述

如果有非字符串键名,会被转换成字符串再创建对象键名


对象转Map

       let obj = {'a':123,'b':456}
       let mObj2 = new Map(Object.entries(obj))
       console.log(mObj2);  // {'a' => 123, 'b' => 456}

在这里插入图片描述


Map转JSON

Map转JSON需要区分两种情况
1、Map键名都是字符串
2、Map键名有非字符串的情况

1、Map键名都是字符串
可以写一个通用函数,用来将Map转为JSON

let j = new Map()
.set('name','东方')
.set('text','不败')

// mapToObj为上面创建的Map转对象的函数
let shiftStrJson = (mapVal) => JSON.stringify(mapToObj(mapVal))
console.log(shiftStrJson(j)); // '{"name":"东方","text":"不败"}'

2、Map键名有非字符串的情况

function shiftMaptoArrayJson(mapVal){
     return JSON.stringify([...mapVal])
}
let j2 = new Map()
.set('name','东方')
.set('text','不败')
let shiftStrJson2 = shiftMaptoArrayJson(j2)
console.log(shiftStrJson2);  // '[["name","东方"],["text","不败"]]'

以上两种的转换结果:
在这里插入图片描述


JSON转Map

JSON转Map需要区分两种情况
1、Map键名都是字符串
2、Map键名有非字符串的情况

1、键名都是字符串

let strObj = '{"name":"东方","text":"不败"}'
let strMap = new Map(Object.entries(JSON.parse(strObj)))
console.log(strMap); // {'name' => '东方', 'text' => '不败'}

2、键名有非字符串情况

let strObj2 = '[["name","东方"],["text","不败"]]'
let strMap2 = new Map(JSON.parse(strObj2))
console.log(strMap2); // {'name' => '东方', 'text' => '不败'}

案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果觉得这篇文章对你有帮助,欢迎点亮一下star哟

标签:Map,set,console,log,详解,let,数据结构,name
From: https://www.cnblogs.com/wang-fan-w/p/17142937.html

相关文章

  • 算法和数据结构新手班课程内容(1~8节)
    01位运算、算法是什么、介绍位运算和简单排序内容:讲解二进制、位运算介绍什么是算法讲解冒泡、选择、插入排序题目:实现打印一个整数的二进制给定一个参数N,返回1!+2......
  • 算法和数据结构新手班课程内容(1~8节)
    01位运算、算法是什么、介绍位运算和简单排序内容:讲解二进制、位运算介绍什么是算法讲解冒泡、选择、插入排序题目:实现打印一个整数的二进制给定一个参数N,返回1!+2......
  • LVS三种工作模式及原理详解
    什么是LVS?摘自:https://blog.csdn.net/qq_59369367/article/details/124951685LVS是LinuxVirtualServer的简写,也就是Linux虚拟服务器,是一个虚拟的服务器集群系统,......
  • 套接字连接以及TCP三次握手详解
    在套接字和地址文章中,我们画出基于套接字接口网络应用的一张图,本文章就是详细解释这些函数具体怎么实现的。socket创建套接字客户端和服务器使用socket函数来创建一个套......
  • 03-Go数组、切片、可变长参数、maps
    1数组#1数组是类似于数字、字符串、的基础数据类型#2数组是同一类型元素的集合eg:整数集合:5,8,9,79,76形成一个数组Go--数组:不允许混合不同类型......
  • leetcode 888. 公平的糖果交换 比较set和map的速度
    求和Sa,Sb找两颗差值=(Sa-Sb)/2的setclassSolution{public:vector<int>fairCandySwap(vector<int>&A,vector<int>&B){intSa=0;int......
  • JSON.toJSONString(object, SerializerFeature.WriteMapNullValue);第二个参数作用
      这里箭头指向的位置,因为sent-1中的value为空,所以并未打印出来。第二个使用:JSON.toJSONString(map,SerializerFeature.WriteMapNullValue)指定序列化方式就打印出......
  • Kroger EDI 855 采购订单确认报文详解
    本文着重讲述KrogerEDI项目中,供应商发给Kroger的X12855EDI规范报文(采购订单确认)解读。在此前的文章如何读懂X12报文中,我们对X12已经做了详细的介绍,大家可以以此为基础......
  • bfs详解
    bfs详解1,bfs的基本概念bfs是广度优先搜索,是一种对树形结构的遍历,他的思想是先选定一个点,从这个点出发,每次只走一步,分为四个方向,直到找到正确答案,相较于dfs的直接递归,bfs......
  • Flutter帧率监控 | 由浅入深,详解获取帧率的那些事
    前言做线上帧率监控上报时,少不了需要弄明白如何通过代码获取实时帧率的需求,这篇文章通过图解配合Flutter性能调试工具的方式一步步通俗易懂地让你明白获取帧率的基础知识,以......