【immutable 学习记录】 immutable 中 map 的用法


什么是immutable

Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

其中有 3 种最重要的数据结构:

Map:键值对集合,对应于 Object,ES6 也有专门的 Map 对象
List:有序可重复的列表,对应于 Array
Set:无序且不可重复的列表

Map 的介绍及 API

// --------- Map 的介绍及 API ------------
// Map 对应原生 js 的 Object 结构, 是无序的键值对集合
// 创建Map,注意:Map是工厂方法,不能使用new初始化

const {Map, List, OrderedMap} = require('immutable')
const m1 = Map({
    x: 1,
    y:2
})
console.log('m1:', m1)

// set 设定值 set(key, value)
const m2 = m1.set('z', 666)
console.log('m2:', m2)
// 原生js中的键 key 要求是一个字符串,在immutable中并没有这个要求
const m3 = m1.set(List([1]), {username:'张三'})
console.log('m3:', m3)

// get 取值
console.log('m2:', m2.get('z'))

// delete 删除值 delete(key)
const d1 = Map({
    username:'zhangsan',
    age: 18
})
const d2 = d1.delete('age')
console.log('d2:', d2)

// deleteAll 批量删除 deleteAll([key1, key2, ...keyN])  删除 N 个key值,只返回一次新的对象
const dal = Map({
    x:1,
    y:2,
    z:3,
    username: 'zhangsan',
    age:18
})
const dal2 = dal.deleteAll(['x','z']) // 删除 x 和 z
console.log('dal2:', dal2)

// clear 清除并返回新的 Map
const cls = dal.clear();
console.log('cls:', cls)

// update 更新, update(key, callback)    callback 可按照某种逻辑把value再加工一次
const sal = Map({
    name:'zhangsan',
    salary: 1000
})
const sal2 = sal.update('salary:', x => x*2)
console.log('sal2:', sal2)

// merge 把 N 个 Map 合并成一个 Map
const mer1 = Map({
    x:1,
    y:2
})
const mer2 = Map({
    y:666,
    z:3
})
const mer3 = mer1.merge(mer2)   // mer2 中的 y 会覆盖 mer1 中的 y
console.log('mer3:', mer3)

// concat 是 merge 的别名 ,一样的用法

// mergeWith 类似于 merge, 但是指定了 merge 的具体规则
const mer4 = mer1.mergeDeepWith((oldVal, newVal)=>{return newVal + '!!!!!'},mer2);   // ()=>{} 这个参数告诉我们如果值有重复的时候我们该怎么办  ---- oldVal来自于mer1, newVal来自于mer2, 如果有重复值则返回 newVal ,但是 newVal要加上!!!!! 即返回值是 newVal!!!!!
console.log('mer4:', mer4)

// setIn 对于嵌套结构来进行设置值  setIn([层次1key, 层次2key, ...层次Nkey], value)
const deepMap = Map({
    lev1: Map({
        lev2: Map({
            lev3: Map({
                lev4: 'good'
            })
        })
    })
})
// 在对象中嵌套赋值时:obj.lev1.lev2.lev3.lev4 = 'good morning
const setIn2 = deepMap.setIn(['lev1','lev2','lev3','lev4'],'good morning')
console.log('setIn2:', setIn2)

// 同样的嵌套层次的操作还有 deleteIn,updateIn,mergeIn ------- key变为 要赋值的value的路径

// toJS 把 map 转换成原生 object   ===== 深转换
const deep = deepMap.toJS()
console.log('deep:', deep)

// toJSON 把 map 转换成原生 object ===== 浅转换
const shallow = deepMap.toJSON()
console.log('shallow:', shallow)

// toArray 把 map 转换成数组    ===== 浅转换
const arrTest = Map({
    x:1,
    y:2,
    z:3
})
const arr = arrTest.toArray()
console.log('arr:', arr)        // 转换之后是键值对的形式

// toObject 把 map 转换成原生 object ===== 浅转换
const json = arrTest.toObject()
console.log('json:', json) 

// equals 判断两个 Map 对象是否相等
const map1 = Map({
    x:1,
    y:2,
    z:3
})
const map2 = Map({
    x:1,
    y:2,
    z:3
})
console.log('map1===map2:', map1===map2)
console.log('equals:',map1.equals(map2))

// find 查找,匹配到的第一个
const findTest = Map({
    x:1,
    y:2,
    z:3,
    username1: '张三'
})
const findResult = findTest.find((val,key) => typeof v === 'String')
console.log('findResult:', findResult)

// findLast 查找,返回最后一个符合的结果

// flatten 扁平化这个 Map   // true 代表浅拉平,只拉平第一层;   false 代表深拉平,拉平N层;    写数值代表拉平到第几层
const flattenTest = Map({
    lev1: Map({
        lev2: Map({
            lev3: Map({
                lev4: 'good'
            }),
            username:'zhangsan'
        })
    }),
    y:2,
    z:3
})
const flat2 = flattenTest.flatten(true);      // ------浅
console.log('flat2:', flat2)
const flat3 = flattenTest.flatten(false);     // ------深
console.log('flat3:', flat3)
// 拉平实际上就是判断是否有 value, 把有 value 的值给拉出来

// has 判断是否存在指定的 key
const hasTest = Map({
    sex: 'male',
    username: 'zhangsan'
})
console.log('has:', hasTest.has('username'))

// includes 判断是否存在指定的 value
const includesTest = Map({
    sex: 'male',
    username: 'zhangsan'
})
console.log('includes:', includesTest.includes('zhangsan'))

// 循环迭代
includesTest.forEach((val, key) => console.log('val:',val, 'key:',key))

// OrderedMap 是有序的 map,迭代输出的顺序是调用set的顺序 ----- 需要更高的开销
const Omap = OrderedMap({})
const Omap2 = Omap.set('z',1)
const Omap3 = Omap2.set('x',2)
Omap3.forEach((v,k) => console.log(k,v))

/**
 * 总结:
 * 1. 对应原生的对象,是无序
 * 2. 循环: forEach 
 * 3. 如果要变为有序的Map,则使用 OrderedMap ,此时的顺序与set的顺序有关
 */

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值