当前位置: 首页 > java >正文

immutable.js介绍

官方文档(英文):Immutable.js 

官网里面有动图和原理讲解

变化的节点重新copy一份之后进行修改,将修改后的值赋值给新的变量,那就需要更改修改之后数据节点的父节点的关系

 0.copy.jsx  拷贝

const obj = { x: 1, b: 2 }
const b = obj
b.x = 'hello'
// 直接拷贝copy
console.log(obj === b); //true
console.log(b.x); //hello
console.log(obj.x); //hello

1.hello_world.jsx

const { Map } = require('immutable')
let a = Map({owner: '张三',car: Map({ name: 'QQ' })
})
// immutable修改数据需要使用set
let b = a.set('owner', '李四')
// 如果修改了某个属性,把这个属性copy一份
console.log('a===b', a === b); //false
// 没有修改,继续共享属性,这样内存节省很大
console.log('a.get("car") === b.get("car")', a.get("car") === b.get("car")); //true
// 数据量很大的情况,只修改了只需要修改的一份,其他的不改变

 2.List.jsx

//List对应原生js的数组结构//创建List, 注意:List是工厂方法,不能使用new初始化
const { List } = require('immutable')
// const list = new List([1,2,3,4])  //NG 不可以这样做!!!  Identifier 'list' has already been declared
const list = List([1, 2, 3, 4])
console.log(list);
//两个静态方法:List.isList()和List.of()
//List.isList()判断是否是List类型
console.log("isList:", List.isList(list));
console.log("isList:", List.isList([2, 3, 4]));
// List.of()创建新的List
const l = List.of(1, 2, 3, 4)
console.log(l);
// size取得List的长度
console.log('size:', l.size);
// set方法用来设定指定下标的值 set(下标,值)
const l2 = List.of(1, 2, 3, 4)
console.log(l2);
l3 = l2.set(0, 110)
console.log('l3:', l3);l4 = l2.set(10, 666)
console.log('l4:', l4);l5 = l2.set(-1, 999)  //这个地方的-1表示从右往左,这样的话,会导致最后一位变成设置数值999
console.log("l5:", l5);//delete删除指定下标的值,delete(下标)
const d1 = List([1, 2, 3, 4])
const d2 = d1.delete(0)
console.log('d2:', d2);// 也支持-负数这样的操作
const d3 = d1.delete(-2)
console.log('d3:', d3);
//insert插入值 insert(下标,值)
const i1 = List([1, 2, 3, 4])
const i2 = i1.insert(1, 666)
console.log("i2:", i2);//update 用来更新指定下标的值(下标,callback)
const u1 = List([1, 2, 3, 4])
const u2 = u1.update(1, x => x + 100)
console.log('u2:', u2);
// clear清空并返回一个长度为0的新数组
const c1 = List([1, 2, 3, 4])
const c2 = c1.clear()
console.log('c1:', c1);
console.log('c2:', c2);// push pop unshift shift同数组的同名方法// setSize 重新设置数组长度,小于原数组长度会截断,大于原数组长度会用undefined进行填充
const set1 = List([1, 2, 3, 4, 5, 6])
const set2 = set1.setSize(2)
console.log("set2:", set2);
const set3 = set1.setSize(20)
console.log("set3:", set3);
// setIn() 用来设定嵌套结构的值 ([第一层下标,第二层下标,...第N层下标],值)
// 同理还有deleteIn,insertIn,updateIn
const arr1 = List([List([1, 2, 3, 4]),List([11, 22, 33, 44]),List([111, 222, 333, 444]),
])
const arr2 = arr1.setIn([2, 1], 0) //[2,1]是位置,表示的是第2行第1列
console.log("arr2", arr2);
console.log("arr1", arr1);
//concat 连接List concat(List1, List2, ..., ListN)
const list1 = List([1, 2, 3, 4, 5])
const list2 = List([11, 22])
const list3 = List([666, 777])
const totalList = list1.concat(list2, list3)
// 会将三个拼成一个数组
// array: [
//   1,  2,   3,   4, 5,
//   11, 22, 666, 777
// ],
console.log('totalList', totalList);
//merge是concat的别名
const totalList2 = list1.merge(list2, list3)
console.log('totalList2', totalList2); //跟merge的返回值一样
// map 同原生的map,循环返回新的List// filter同原生的filter,循环过滤并返回新的List// flatten 扁平化这个list
const fl1 = List([List([1, 2, 3, 4]),List([11, 22, 33, 44]),List([111, 222, 333, 444]),
])
const fl2 = fl1.flatten(true); //false:会将里面的N层全部拉平,true只会将里面的第一层全部拉平,成为一个数组
// 如果数组只有第一层,那么就true就可以了,如果里面的多层,那么就添false,将所有层的拉平到一个数组
console.log("fl2", fl2);
// 最终结果
// array: [
//   1,   2,  3,   4,  11,
//  22,  33, 44, 111, 222,
// 333, 444
// ],
// find 查找,返回第一个符合的结果
const names = List(['张三', '樟树市', '李四', '张武'])
const names2 = names.find((v, k) => v.indexOf('张' !== -1))  //字符串的一个查找方法
console.log('names2:', names2); //张三
// findLast 查找,返回最后一个符合的结果
const names3 = names.findLast((v, k) => v.indexOf('张' !== -1))  //字符串的一个查找方法
console.log('names3:', names3);//张武
// keys返回所有的下标,索引
const keys = names.keys()
console.log('keys', keys); //keys Iterator { next: [Function (anonymous)] }
for(const k of keys){console.log('k:', k);
}
/*k: 0k: 1k: 2k: 3*/
// values 返回所有的值,名字
const values = names.values()
console.log(values); //返回的也是一个迭代器
for(const v of values){console.log('v:', v);
}
/*v: 张三v: 樟树市v: 李四v: 张武*/
// entries 返回所有entry,(key,value)形式
const entries = names.entries()
console.log(values); //返回的也是一个迭代器
for(const entry of entries){console.log('entry:', entry);
}
// 即包含key也包含value
/*entry: [ 0, '张三' ]entry: [ 1, '樟树市' ]entry: [ 2, '李四' ]entry: [ 3, '张武' ]*/
// groupBy分组
const people = List([{sex: "male",name: '张三'},{sex: "male",name: '李四'},{sex: "male",name: '王五'},{sex: "female",name: '玛丽'},
])
const gp = people.groupBy(x=>x.sex);
console.log('gp:', gp);

3.Map.js

// Map对应原生js的Object结构,它是无序的// Map是工厂方法,不要使用new实例化
const { Map, List } = require('immutable')
const m1 = Map({x: 1,y: 2
})
console.log("m1:", m1);
// set设定值 set(key,value)
// 设置新的值z为666
const m2 = m1.set('z', 666)
console.log('m2', m2);
// 设置一个新的List列表
const m3 = m1.set(List([1]), { username: "zhangsan" });
console.log('m3:', m3);
// get取值
console.log(m2.get('z')); //666
//delete删除值 delete(key)
const d1 = Map({username: 'zhangsan',age: 18
})
const d2 = d1.delete('age')
console.log('d2:', d2);
for (const entry of d2) {console.log('entry:', entry);
}
// entry: [ 'username', 'zhangsan' ]
// deleteAll批量删除,deleteAll([key1, key2, ...keyN])
const dal = Map({x: 1,y: 2,z: 3,username: 'zhangsan'
})
const dal2 = dal.deleteAll(['x', 'z'])
console.log('dal2', dal2);
/*entry: [ 'username', 'zhangsan' ]entry: [ 'y', 2 ]
*/
// clear清除所有返回新的Map
const cls = dal.clear()
console.log('cls:', cls);
//update更新 update(key,callback)
const sal = Map({name: 'zhangsan',salary: 1000
})
const sal2 = sal.update("salary", x => x * 2)
console.log('sal2', sal2);
// merge合成N个Map为一个Map merge(map1,map2, ...mapN)
const mer1 = Map({x: 1,y: 2
})
const mer2 = Map({y: 666,z: 3
})
const mer3 = mer1.merge(mer2)
console.log('mer3:', mer3);
// concat是merge的别名// mergeWith类似于merge,但是指定了merge的具体规则
// 当旧值与新值重复的时候使用新值,但是新值要加上!!!
const mer4 = mer1.mergeWith((oldVal, newVal) => { return newVal + '!!!' }, mer2)
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// toJS 把map转换成原生object,深转换
const deep = deepMap.toJS()
console.log('deep:', deep);
// toJSON 把map转换成object,浅转换
const shallow = deepMap.toJSON()
console.log("shallow:", shallow);
// toArray转换成数组,浅转换
const arrTest = Map({x: 1,y: 2,z: 3
})
const arr = arrTest.toArray()
console.log('arr:', arr);
/*
每一个key————value都对应了原来的键值对
arr: [ [ 'x', 1 ], [ 'y', 2 ], [ 'z', 3 ] ]
*/
// toObject转换成Object,浅转换
const json = arrTest.toObject()
console.log('json:', json); //json: { x: 1, y: 2, z: 3 }
// 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); //false,地址值不同,不会相等
console.log('equals:', map1.equals(map2)); //true,判断两个map对象的值是否相等
// find查找,匹配到的第一个
const findTest = Map({x:1,y:2,z:3,username1: '张三',username2: '李四'
})
const findResult = findTest.find((val,key)=>val==='张三')
console.log('findResult:', findResult); //张三
// findLast 查找,匹配到的最后一个// flatten拉平Map
const flatTest = Map({lev1: Map({lev2: Map({lev3: Map({lev4: 'good'}),username: 'zhangsan'})}),y:2,z:3
})
const flat2 = flatTest.flatten(true)
console.log('flat2:', flat2); //只将第一层的数据拉平
const flat3 = flatTest.flatten(false)
console.log('flat3:', flat3); //将所有数据都拉平到一层
/*entry: [ 'lev4', 'good' ]entry: [ 'y', 2 ]entry: [ 'z', 3 ]
*/
// has判断是否有指定的key
const hasTest = Map({sex: 'male',username: 'zhangsan'
})
console.log('has:', hasTest.has('username')); //true
// includes判断是否有指定的value
const includeTest = Map({sex: 'male',username: 'zhangsan'
})
console.log('includes:',includeTest.includes('zhangsan'));//true
//forEach方法
includeTest.forEach((val,key)=>console.log('val:', val, 'key:', key))
/*val: male key: sexval: zhangsan key: username
*/
for (const entry of flat3) {console.log('entry:', entry);
}

浅转换,深转换,最终执行结果

flatten拉平结果

4.OrderedMap.jsx

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

5.Set.jsx

// Set 可以理解为value唯一的数组,即数组中不允许出现重复的值// Set是工厂方法,不允许new来实例化,会自动去重
const {Set} = require('immutable')
const set = Set([1,2,3,4,5,2,2,2,1])
console.log(set);
/*
已经去重过的结果
entry: 1
entry: 2
entry: 3
entry: 4
entry: 5
*/
// add添加值
const add1 = set.add(6)
console.log('add1:', add1);
// delete删除值
const del1 = set.delete(2)
console.log(del1);
/*
无序的列表
entry: 1
entry: 5
entry: 3
entry: 4
*/
// clear清空并返回新Set
const cls1 = set.clear()
console.log(cls1);
// union N个set合并成一个set
const s1 = Set([1,2,3])
const s2 = Set(['x','y','z'])
const union = s1.union(s2)
console.log('union:', union);
/*
entry: 1
entry: 2
entry: 3
entry: x
entry: y
entry: z
*/
// intersect 取N个set的交集
const in1 = Set([1,2,3,4,5,6])
const in2 = Set([2,4,6,8,10])
const resultIntersect = in1.intersect(in2)
console.log('resultIntersect:',resultIntersect);
/*
entry: 6
entry: 2
entry: 4
*/
// subtract 从set除去一些值
const sub1 = Set([1,2,3,4,5,6,7,8,9])
const sub2 = sub1.subtract([1,5,9])
console.log('sub2:',sub2);
/*
entry: 2
entry: 3
entry: 4
entry: 6
entry: 7
entry: 8
*/
// forEach 循环
const each1 = Set(['x','y','z'])
each1.forEach((val,key)=>console.log(key,val))
// get 取得值
const setArr = Set(['x', 'y', 'z'])
console.log('setArr.get(2):', setArr.get(2)); //undefined
console.log('get:', setArr.get('z')); //z
// has 判断是否包含指定的key
console.log('has:', setArr.has('y')); //true
// include 判断是否包含指定的value
console.log('includes:', setArr.includes('y')); //true
//rest除了第一个的其余元素
const r1 = Set([1,2,3,4,5,6])
const r2 = r1.rest()
console.log('r2:', r2);
//butLast除了最后一个元素的其余元素
const b1 = Set([1,2,3,4,5,6])
const b2 = b1.butLast()
console.log(b2);
// skip(number)略过前N个元素,取得其余元素
const sk1 = Set([1,2,3,4,5,6])
const sk2 = sk1.skip(3)
console.log(sk2);
/*
entry: 4
entry: 5
entry: 6
*/
// skipLast(number) 略过最后N个元素,取得其余元素
const skL1 = Set([1,2,3,4,5,6])
const skL2 = sk1.skipLast(3)
console.log(skL2);
/*
entry: 1
entry: 2
entry: 3
*/
// skipWhile((value: T, key: T, iter: this)=>boolean) 当判断条件为false时,取得当前以及后面的元素
const skw1 = Set(['hello','world','good','bad','just','little'])
const skw2 = skw1.skipWhile(item=>item.indexOf('o')!==-1) //在‘bad’的时候item.indexOf('o')值为-1,判断条件返回为true
console.log('skw2:', skw2);
/*
entry: bad
entry: just
entry: little
*/
// skipUntil((value: T, key: T, iter: this)=>boolean) 当判断条件为true时,取得当前以及后面的元素
const sku1 = Set(['hello', 'world', 'good', 'bad', 'just', 'little'])
// const sku2 = sku1.skipUntil(item=>item.indexOf('o')===-1) //这样的判断条件说明里面并不等于o
// 正则写法
const sku2 = sku1.skipUntil(item=>!/o/g.test(item)) //这样的判断条件说明里面并不等于o
console.log('sku2:', sku2);
/*
entry: bad -1
entry: just -1
entry: little -1
*/
//take(number) 取得前N个元素
const take1 = Set([1,2,3,4,5,6])
const take2 = take1.take(2)
console.log('take2:',take2);
// takeLast(number) 取得最后N个元素
const take3 = take1.takeLast(2)
console.log('take3:',take3);
// takeWhile((value: T, key: T, iter: this)=> boolena) 从前向后取元素,当判断条件为false时为止
const tw1 = Set([2,4,6,8,1,3,5,7,9])
console.log('tw1:', tw1);
const tw2 = tw1.takeWhile(item => item % 2 === 0)
console.log('tw2:', tw2);
// takeUntil((value: T, key: T, iter: this)=> boolena) 从前向后取元素,当判断条件为true时为止for (const entry of tw2) {console.log('entry:', entry);
}

6.OrderedSet.jsx

// OrderedSet是有序的Set,它的顺序是调用add添加元素的顺序,拥有Set的所有方法和属性
const { OrderedSet,Set } = require('immutable')
const oset = OrderedSet([2, 4, 6, 8, 1, 3, 5, 7, 9])
console.log('oset:', oset);
const set = Set([2,4,6,8,1,3,5,7,9])
console.log('set:', set); //无序的const result = oset.takeWhile(item=>item%2 === 0)
console.log('result:', result);// sort 排序方法 sort((valueA: T, valuueB: T)=>number)
// valueA - valueB:升序
// valueB - valueA: 降序
const sort1 = oset.sort((valA,valB)=>valA-valB)
console.log('sort1:', sort1);
const sort2 = oset.sort((valA,valB)=>valB-valA)
console.log('sort1:', sort2);for (const entry of sort2) {console.log('entry:', entry);
}
// 推荐使用

7.Seq.jsx

// Seq描述了一个“懒”操作,允许使用collection的高阶方法的高效的链式调用,但是不会生成中间的collection
// 特点1:Seq is immutable Seq是不可改变的
// 特点2:Seq is lazy Seq是懒的
const { Seq} = require("immutable");
// 由于Seq是lazy的,因此下面的链式调用是不会被立即执行的,只有当oddSquares被调用的时候,才会被执行
const oddSquares = Seq([1, 2, 3, 4, 5, 6, 7, 8]).filter((x) => x % 2 !== 0).map((x) => x * x);
console.log('oddSquares', oddSquares);
// 可以通过Seq方法把任意collection转换成Seq
const {List,Map,Set} = require('immutable')
const list = List([1,3,2,4])
const seq1 = Seq(list)
console.log('seq1', seq1); //当贝调用的时候才会被执行
const map = Map({x: 1, y:2, z:3})
const seq2 = Seq(map)
console.log('seq2', seq2);
const set = Set([1,3,5,7,9])
const seq3 = Seq(set)
console.log('seq3',seq3)//Seq.keyed
const obj = {x:1,y:2,z:3}
const seqK = Seq.Keyed(obj)
console.log('seqK:',seqK);
/*
entry: [ 'x', 1 ]
entry: [ 'y', 2 ]
entry: [ 'z', 3 ]
*/
//Seq.Indexed
const arr = [1,2,3,4,5,6]
const seqI = Seq.Indexed(arr)
console.log('seqI:', seqI);
/*
entry: 1
entry: 2
entry: 3
entry: 4
entry: 5
entry: 6
*/
//Seq.Set
const setset = Set([11,11,22,22,33,33])
const seqSet = Seq.Set(setset)
console.log('seqSet:', seqSet);
/*
entry: 11
entry: 22
entry: 33
*/
for (const entry of seqSet) {console.log('entry:', entry);
}
// collection 集合包括 List(一个有一个的数组),Map(键值对的形式),Set(数组去重)

8.immutable对象和原生对象的相互转换.jsx

// 原生对象转immutable对象
// formJS() 能够把原生的数组或者对象转换成对应的List或者Map
const immutable = require('immutable')
const map = immutable.fromJS({x:1,y:2,z:3,xyz:{good: 123
}})
console.log('map', map);
const list = immutable.fromJS([1,2,3,[44,55,66]])
console.log('list:', list);
const list_map = immutable.fromJS([1,2,3,[{x:1,y:2},{a:3,b:4},
]])
console.log('list_map', list_map);
// immutable对象转原生对象
// toJS() 转换为原生对象
//    List -> 数组
//    Set -> 数组
//    Map -> 数组
const {List,Map,Set} = require('immutable')
const ls = List([1,2,3,4])
const arr1 = ls.toJS()
console.log('arr1:', arr1); //mp
const mp = Map({x:1,y:2})
const obj = mp.toJS()
console.log('obj:', obj); //{ x: 1, y: 2 }
const st = Set([11,22,22,22,33])
const arr2 = st.toJS()
console.log('arr2:', arr2); //[ 11, 22, 33 ]for (const entry of list_map) {console.log('entry:', entry);
}

9.others.jsx

// Range(start?: number,end?: number, step?: number) 根据给定的范围生成一个Seq
const { Range } = require('immutable')
const r1 = Range(0, 5)
console.log('r1:', r1);
const r2 = Range(6, 15, 2)
console.log('r2:', r2);
r2.forEach(item=>console.log(item))
/*68101214
*/
// Request(value,times) 重复生成N个值的Seq,当没有传入times的时候,会生成长度为infinite的Seq
const { Repeat} = require("immutable");
const repeat1 = Repeat(666)
console.log('repeat1:', repeat1); //repeat1: Repeat { _value: 666, size: Infinity }
const repeat2 = Repeat(999, 20)
console.log('repeat2:', repeat2);
repeat2.forEach(item => console.log(item))

练习的详细代码,在react当中的使用看后面,官网当中有具体文档介绍

http://www.xdnf.cn/news/5427.html

相关文章:

  • 【Diffusion】在华为云ModelArts上运行MindSpore扩散模型教程
  • 深入浅出之STL源码分析2_stl与标准库,编译器的关系
  • 解决VirtualBox中虚拟机(ubuntu)与主机(windows)之间互相复制粘贴(文本)
  • 文件批量重命名工具,简单高效一键完成更名
  • 【常用算法:排序篇】4.高效堆排序:线性建堆法与蚂蚁问题的降维打击
  • kubectl系列(十二):查询pod的resource 配置
  • Java定时任务
  • Cribl 利用CSV 对IP->hostname 的转换
  • tokenizer.encode_plus,BERT类模型 和 Sentence-BERT 他们之间的区别与联系
  • 数据结构练习:顺序表题目
  • terraform云上实战(一):执行阿里云云助手命令
  • C++ string初始化、string赋值操作、string拼接操作
  • Celery 在分布式任务调度中的实现原理及 MQ 系统对比
  • GIF图像技术介绍
  • 隐马尔可夫模型(HMM)在彩票预测中的Java实现
  • OpenCV进阶操作:指纹验证、识别
  • 复现MAET的环境问题(自用)
  • Javascript基础语法
  • 【STM32开发】-单片机开发基础(以STM32F407为例)
  • SEO长尾关键词布局优化法则
  • 虚拟内存笔记(三)虚拟内存替换策略与机制
  • 前端项目打包部署流程j
  • 北大闰凯博士:热辐射输运问题蒙特卡罗模拟中的全局最优参考场方法
  • HTOL集成电路老化测试学习总结-20250510
  • Linux : 多线程【线程概念】
  • ssh -T git@github.com 测试失败解决方案:修改hosts文件
  • 计算机基础
  • 深入了解linux系统—— 自定义shell
  • 24、TypeScript:预言家之书——React 19 类型系统
  • MYSQL语句,索引,视图,存储过程,触发器(一)