前言: 在以外的开发中,接触过Map这个对象,但是只限于在代码里看见过,还没有自己去了解并且写过,今天碰到个需求时发现使用Map 对象真香,写此文章加深印象。
Map
-
Map 对象存有键值对,其中的键可以是任何数据类型。
-
Map 对象记得键的原始插入顺序。
-
Map 对象具有表示映射大小的属性。
Map是一组键值对的结构,具有极快的查找速度。
使用
初始化一个空Map。Map具有以下方法:(常用)
var m = new Map(); // 空Map
m.set('Lili', 33); // 添加新的key-value
m.set('Job', 15);
m.has('Lili'); // 是否存在key 'Lili': true
m.get('Lili'); // 33
m.delete('Lili'); // 删除key 'Lili'
m.get('Lili'); // undefined
由于一个key只能对应一个value,所以重复设置key,后面的值会覆盖前面的值:
var m = new Map(); // 空Map
m.set('yang', 18);
m.set('yang', 20);
m.get('yang'); // 20
打印Map对象如下:size 代表Map 中元素的数量
一般需要循环取值时,可以使用for of
for (let [key, value] of m) {
console.log(key, value);
}
场景
接到一个需求是在表格中对有重复名称的名字时,需要把当前这行数据标红(后面觉得一片红不好看改为只标红名字)。这次使用Map对象实现改功能。因为Map重复set一个相同的key值会覆盖之前的,就可以判断有重复名字时进行数量的++,然后渲染数据的时候判断数量在给每条数据定义个标识就可以实现标红了。
- 首先就是对拿到了lis数据进行循环
var m = new Map()
list.forEach(el => {
let num = 1 // 定义个基础值为1
if (m.has(el.name)) { // 判断Map对象里是否存在当前名字,存在拿到当前名字key取出值进行+1
num = m.get(el.name) + 1
m.set(el.name, num)
} else {
m.set(el.name, num) // 不存在就以名字设置为key,值为1
}
});
得到如下Map对象:
2. 再根据值大于1.给当前对象添加一个标识
list.forEach(el => {
if (m.get(el.name) > 1) { // 取出当前名字为key的值,大于1定义标识为true
el.isFlag = true;
} else {
el.isFlag = false;
}
});
- 在列表渲染
<el-table-column
label="姓名"
width="180">
<template slot-scope="scope">
<span style="color:red;" v-if="scope.row.isFlag">${row.name===null?'': row.name}</span>
<span v-else>${row.name===null?'': row.name}</span>
</template>
</el-table-column>
页面效果如下:
Set
-
Set 是唯一值的集合。
-
每个值在 Set 中只能出现一次。
-
一个 Set 可以容纳任何数据类型的任何值。
使用
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
注意数字3和字符串’3’是不同的元素。
场景
在Set中,没有重复的key,一般面试题的数组去重也可以使用到。
- 可以使用扩展运算符
let arr = [15,25,36,52,25,15]
let item = [...new Set(arr)]
console.log(item); // [15,25,36,52]
- 也可以使用Array.from
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
let arr = [15,25,36,52,25,15]
let item = Array.from(new Set(arr))
console.log(item); // [15,25,36,52]