Set 初步介绍
ES6变化 - Set、Map
简介:
Set是ES6提供给我们的构造函数,能够造出一种新的存储数据的结构
特点:
只有属性值,成员值唯一(不重复)
用途:
可以转成数组,其本身具备去重,交集,并集,差集的作用等
// 参数需具备迭代接口 [ ]、arguments NodeList
new Set( [1, 2, 3] )
Set.add()
Set.delete()
Set.clear()
Set.has()
oS.forEach( val => {
console.log(val)
} )
ES6 for of 需要具备迭代接口才能使用
for (let prop of [ 'a', 'b' ]){
console.log(prop)
}
// 数组转化为Set
let arr = [1, 2 ,3, 4, 5]
let oS = new Set( arr )
// Set 转化为 数组
// ... 扩展运算,可扩展任意具有迭代接口的值
// Array.form 将具备迭代接口的数据 转化为数组
Array.from( oS ) // [1, 2, 3, 4, 5]
[ ...oS ] // [ 1, 2, 3, 4, 5 ]
数组去重
let arr = [ 1,2 ,3, 4, 5, 6, 1, 2, 3 ] let obj = {} let newArr = [] for ( let i = 0; i < arr.length; i++ ) { if ( !obj [ arr[i] ] ) { newArr.push( arr[i] ) obj[ arr[i] ] = true } } 有缺陷,当传入对象的时候会出现错误
let oS = new Set(arr)
// 并集 交集 和 差集
// 并集
let arr1 = [ 1, 2, 3, 2, 3 ]
let arr2 = [ 3, 2, 4, 4, 5 ]
let oS = new Set( ...arr1, ...arr2 )
// 交集
let oS1 = new Set(arr1)
let oS2 = new Set(arr2)
[...oS1].filter( ele => {
return oS2.has(ele)
} )
// 差集
let newArr1 = [...oS1].filter( ele => {
return !oS2.has(ele)
} )
let newArr2 = [...oS2].filter( ele => {
return !oS1.has(ele)
} )
[...newArr1, ...newArr2]
ES6变化 - Map
简介:
Map 是ES6提供给我们的构造函数,能够造出一种新的存储数据的结构。本质上是键值对的集合
特点:
key对应value,key和value唯一,任何值都可以当属性
用途:
可以让对象当属性,去重等
原理实现:
邻接链表、hash算法、桶
let oMp = new Map([ ['name', 'as'], ['age', '23'], ['sex', 'male'], [ {}, '----' ] ]) // oMp( 'name' => 'as', 'age' => '23', 'sex' => 'male', {} => '----' ) // api let oMp = new Map() oMp.set('name', 'cst') oMp.set('age', 18) oMp.set({}, '----') oMp.set({}, '++++') // get 取值 oMp.get() oMp.delete() oMp.clear() oMp.size() oMp.keys() // 属性名 MapIterator { "name" , "age" } oMp.entries() // 属性名和属性值拼一个对返回 MapIterator { "name" => "cst", "age" => 18 } // forEach oMp.forEach( (ele, key, self) => { } ) for (let val of oMp) { console.log(val) // ["name", "cst"] ["age", 18] console.log(val[0], val[1]) // name cst age 18 }
//has
oMp.has('name') // true
for (let val oMp.keys()) { console.log(val) // name age }
ES6 Map 存储原理
// Map 实现
// 链表
let node1 = {
key: 'name',
value: '1',
next: node2
}
let node2 = {
key: 'name2',
value: '2',
next: node3
}
let node3 = {
key: 'name3',
value: '3',
next: null
}
let oMp = new Map( [ [ 'name1', '1' ], [ 'name2', '2' ] ] )
// hash 特定范围的值
把不定的值变为特定的值都叫为hash 算法 eg:Math.random() * 10 + 5 5 - 15
// 桶
[
{
key: 'name1',
value: '1',
next: {
key: 'name2',
value: '2'
}
},
{},
{},
{},
{},
{},
{},
{}
]
Map 模拟实现
1. 不重复
2. 字符串 对象 NaN null [ ] function(){} 10
3. delete set get has clear
let prop = 'name'
let obj = {
[prop + 10] : 'cst'
}
function myMap () { this.bucketLength = 8 this.init() } myMap.prototype,init = function () { // 初始化 桶 8 this.bucket = new Array( this.bucketLength ) for ( var i = 0; i < this.bucket.length; i++ ) { this.bucket[i] = { type: 'bucket_' + i, next: null } } } // 1. [ 0, 8 ] // 2. 重复算值固定 myMap.prototype.makeHash = function (key) { // string number boolean null undefined NaN {} [ ] function (){} let hash = 0 if ( typeof key !== 'string' ) { if ( typeof key == 'number' ) { // Object.is( NaN, NaN ) true 完全长一样就相等 hash = Object.is( key, NaN ) ? 0 : key }else if (typeof key == 'object') { // null {} [ ] hash = 1 }else if ( typeof key == 'boolean' ) { // true false hash = Number(key) }else { // undefined function() {} hash = 2 } }else { // string // 'a' 'ab' 'asfdfaffsa' // 长度大于等于3 前三个字符 ASCII 累加 for ( let i = 0; i < 3; i++ ) { hash += key[i] ? key[i]charCodeAt(0) : 0 } } return hash % 8 } myMap.prototype.set = function (key, value) { let hash = this.makeHash(key) let oTempBucket = this.bucket[ hash ] while ( oTempBucket.next ) { if ( oTempBucket.next.key == key ) { oTempBucket.next.value = value }else { oTempBucket = oTempBucket.next } } oTempBuck.next = { key: key, value: value, next: null } } myMap.prototype.get = function ( key ) { let hash = this.makeHash(key) let oTempBucket = this.bucket[ hash ] while( oTempBucket ) { if (oTempBucket.key == key) { return oTempBucket.value } else { oTempBucket = oTempBucket.next } } return undefined } myMap.prototype.delete = function (key) { let hash = this.makeHash(key) let oTempBucket = this.bucket[ hash ] while ( oTempBucket.next ) { if ( oTempBucket.next.key == key ) { oTempBucket.next = oTempBucket.next.next return true } else { oTempBucket = oTempBucket.next } return false } } myMap.prototype.has = function () { let hash = this.makeHash(key) let oTempBucket = this.bucket[ hash ] while ( oTempBucket) { if (oTempBucket.next && oTempBucket.next.key == key ) { retrun true } else { oTempBucket = oTempBucket.next } return false } myMap.prototype.clear = function (key) { // this.bucket = new Array(this.bucketLength) this.init() } let oMp = new myMap() oMp.set( 'name', 'cst' )