ES6中Set和Map数据结构(2)

ES6提供了新的数据结构 Set 和 Map。
上一篇:Set 数据结构

Map

在JavaScript中对象(Object),本质上是键值对的集合,但是传统上只能用字符串当作键,ES6中的 Map 数据结构也是键值对的集合,但是它的键不限与于字符串,各种类型的值包括对象都可以当作键。

//ES5 中Object
const data = {
     };
const element = document.getElementById('myDiv');

data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"

//ES6 中 Map
const m = new Map();
const o = {
     p: 'Hello World'};

m.set(o, 'content')
console.log(m.get(o)) // "content"

const a = ["name"];
m.set(a,"zsl");
console.log(m.get(a)) // "zsl"

Map 作为构造函数可以接受数组作为参数。

//示例一
const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

//示例二
const items = [
  ['name', '张三'],
  ['title', 'Author']
];

const map = new Map();

items.forEach(
  ([key, value]) => map.set(key, value)
);

当 Map 作为构造函数参数为数组的时候(上示例一),实际执行的是示例二的步骤。

Map 实例的属性和操作方法
Map 结构的实例有以下属性和操作方法。

  • size 属性:size属性返回 Map 结构的成员总数。
  • Map.prototype.set(key, value):set方法设置键名key对应的键值为value,然后返回整个 Map
    结构。如果key已经有值,则键值会被更新,否则就新生成该键。
  • Map.prototype.get(key):get方法读取key对应的键值,如果找不到key,返回undefined。
  • Map.prototype.has(key):has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
  • Map.prototype.delete(key):delete方法删除某个键,返回true。如果删除失败,返回false。
  • Map.prototype.clear():clear方法清除所有成员,没有返回值。
const m = new Map();
m.set('a', 1);
m.set('b', 2);

console.log(m.size); //2

console.log(m.get('a')); //1

console.log(m.has('a')); //true
console.log(m.has('b')); //true
console.log(m.has('c')); //false

m.delete('b');
console.log(m.has('b')); //false
console.log(m.size); //1

m.clear();
console.log(m.size); //0

遍历方法
Map 结构原生提供三个遍历器生成函数和一个遍历方法。Map 的遍历顺序就是插入顺序。

  • Map.prototype.keys():返回键名的遍历器。
  • Map.prototype.values():返回键值的遍历器。
  • Map.prototype.entries():返回所有成员的遍历器。
  • Map.prototype.forEach():遍历 Map 的所有成员。
const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
     
  console.log(key);
}
// "F"
// "T"

for (let value of map.values()) {
     
  console.log(value);
}
// "no"
// "yes"

for (let item of map.entries()) {
     
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
     
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
     
  console.log(key, value);
}
// "F" "no"
// "T" "yes"


//forEach方法
const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);
map.forEach((value, key) => console.log(key,value));
// "F" "no"
// "T" "yes"

Map 的应用

Map 于其他数据结构的互相转换。

//(1)Map 转为数组

const myMap = new Map()
  .set(true, 7)
  .set({
     foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]



//(2)数组 转为 Map

new Map([
  [true, 7],
  [{
     foo: 3}, ['abc']]
])
// Map {
     
//   true => 7,
//   Object {foo: 3} => ['abc']
// }



//(3)Map 转为对象

function strMapToObj(strMap) {
     
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
     
    obj[k] = v;
  }
  return obj;
}

const myMap = new Map()
  .set('yes', true)
  .set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }



//(4)对象转为 Map

function objToStrMap(obj) {
     
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
     
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({
     yes: true, no: false})
// Map {"yes" => true, "no" => false}



//(5)Map 转为 JSON

 1. //Map 的键名都是字符串,这时可以选择转为对象 JSON。
  function strMapToJson(strMap) {
     
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'

 2. //Map 的键名有非字符串,这时可以选择转为数组 JSON。
  function mapToArrayJson(map) {
     
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({
     foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'6JSON 转为 Map

 1. //所有键名都是字符串

function jsonToStrMap(jsonStr) {
     
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}

 2. //整个 JSON 就是一个数组
function jsonToMap(jsonStr) {
     
  return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

Map 间接使用数组的 map 和 filter 方法 。

const map0 = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');

const map1 = new Map(
  [...map0].filter(([k, v]) => k < 3)
);
// 产生 Map 结构 {1 => 'a', 2 => 'b'}

const map2 = new Map(
  [...map0].map(([k, v]) => [k * 2, '_' + v])
    );
// 产生 Map 结构 {2 => '_a', 4 => '_b', 6 => '_c'}

总结

Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。这意味着,可以省略values方法,直接用for…of循环遍历 Set。

Set.prototype[Symbol.iterator] === Set.prototype.values  //true

//用for...of循环遍历 Set
let set = new Set(['red', 'green', 'blue']);
for (let x of set) {
     
  console.log(x);
}
// red
// green
// blue

Map 结构的默认遍历器接口(Symbol.iterator属性),就是 entries 方法。这意味着,可以省略 entries 方法,直接用for…of循环遍历 Map。

map[Symbol.iterator] === map.entries   //true 

//用for...of循环遍历 Set
const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);
for(let x of map){
     
    console.log(x)
}
//["F", "no"]
//["T", "yes"]

Set 数据结构可以看上一篇笔记:ES6中Set和Map数据结构(1)

你可能感兴趣的:(ES6,ES6中Set,和,Map,数据结构)