美文网首页
02基础操作

02基础操作

作者: 我_巨可爱 | 来源:发表于2017-10-30 17:06 被阅读0次

一个说明不可变的例子

// 如果只改变 Immutable 对象的某个节点,那么该节点和父节点改变,其他共享
let a = Immutable.formJS({
    naem: 'yf',
    age: 19,
    friend: {
        name: 'yhx',
        age: 9
    }
})
let b = a.set('name':'yy');
console.log(a === b); // false
console.log(a.get('friend') === b.get('friend'))

immutable中的数据结构

常用的也就是 List , Map ,顶多加个 Seq

  • List 有序索引集,类似于Array
  • Map 类似于Object
  • OrderedMap 有序 Map,排序依据是数据的set()操作
  • Set 类似于ES6中set,不重复无序值的集合
  • OrderedSet 有序 Set,排序依据是数据的add操作
  • Stack 有序集合,使用unshiftshift进行操作
  • Seq 序列
  • Range() 返回一个Seq.Indexed类型的数据结合,该方法接受三个参数(start = 1,end = infinity,step = 1),分别表示起始点/终止点和补偿,如果start等于end,则返回空的数据集合
  • Repeat() 返回一个Seq.indexed类型的数据集合,该方法接受两个参数(value,times),value表示重复生成的值,times表示重复生成的次数,没有则表示生成无限个
  • Record 类似于 ES6 中的 Class,但在细节上还有所不同
  • Iterable 可以被迭代的(key,value)键值对结合,是基类,为其他所有集合提供了基础的Iterable操作函数(比如 map 和 filter)
  • Collection 创建 Immutable 对象最基础的抽象类,不能直接构造该类型

几个重要的API

fromJS()

  1. 接受两个参数
  • json 数据
  • reviver 函数
  1. 在不传递 reviver 函数的情况下,默认将原生JS的 Array 转化成 List, Object 转化成 Map
  2. 其他原生类型原封不动返回

is()

  1. Immutable 数据不应该被看成对象,应该看成该事件在特定时刻的状态
  2. 使用Immutable.is()两个参数,不仅可以比较 Immutable 类型的数据

Map

  1. 对应的是 Map 数据类型,对应原生 Object ,对象 key 可是是任意值
console.log(Map().set(List.of(1),'list-of-one').get(List.of(1)))
console.log(Map().set(NaN,'NaN').get(NaN));
console.log(Map().set(undefined,'undefined').get('undefined'));

简单介绍 OrderMap

  1. 有序 Map
  2. 顺序按 添加或声明 的顺序
  3. 会消耗更多内存
  4. 如果要求遍历有序,请使用 List

List

和原生 Array 最大的区别,不产生空位,即没有[,,,]

API

构造函数 Map() List()

  1. 该构造函数不常用
  2. 同key覆盖

另一种方式 of()

  1. 通过Map.of()
  2. 通过List.of()

判断是否是一个 Map 或者 List

  1. Map.isMap()
  2. List.isList()

获取大小

Immutable 对象上的属性和方法

  1. 属性size
  2. count方法,可以传入函数
  3. countBy方法,返回一个对象

添加元素

使用 set 不仅可以添加数据,还可以改变数据

  1. set在 List 中,使用索引,在 Map 中,使用属性
  2. setIn 第一个参数是路径

List 特有的添加元素

因为 List 是有原生JS数组转化,因此有很多添加元素的方法

  1. inset(inex,value)
  2. setSize(length),当设置很长的时候,会填充undefined
  3. pop/push/shift/unshift删除和添加元素
  4. 花样插入
  • interpose(separator)每两项中间添加 separator
  • interleave(immutable List)被操作的两个数组,每个的第一项,第二项,第三项...组成新的数组
  • zip(),被操作的两个数组,抽离第一项和第二项组成新的子数组,放入到一个大数组中,形成二维数组
  • zipWith(),自定义插入规则

删除元素

  1. delete()
  2. deleteIn() 使用方式和上边的 setIn 一样
  3. clear()

修改元素

  1. set/setIn
  2. update()
  3. updateIn()
// 第一个是要改变的数组项对应的索引,第二个是找不到对应数组项时的默认值,第三个是带默认参数的函数
update(key: K, notSetValue: V, updater: (value: V) => V): Map<K, V>

获取某个元素值

  1. get(key,notSetValue)只有数组可以key可以使用 number,即使对象{1:'hehe'}也是不能数 number 类型的1,需要用 string 类型的1
  • notSetValue 获取不到时的默认值
  1. getIn()
  2. first()获取头元素
  3. last()获取尾元素

查找某个元素

  1. find(function (val,index,array) {})可以自定义查找条件,比如索引,数值。返回value。findLast()使用方式同上,是倒序
  2. findKey(function (val,index,array) {})自定义查找条件,返回key。findLastKey()使用方式同前边,但是是倒序
  3. findEntry()返回 [key,value]findLastEntry()是倒序。注意,示例中,value好像不是数组项或者对象属性值,而是Immutable 数据类型。
  4. keyOf()根据value返回key。lastKeyOf()倒序
// List
console.log(Immutable.fromJS([1, 2, 3, {a: {b: 111}}]).findEntry((value, index, array) => {
    return index === 3;
}));// [3, Map]

// Map
console.log(Immutable.fromJS({a: {a1: 222}, b: 2, c: 3, d: 444}).findEntry((value, key, obj) => {
    return Immutable.is(value, Immutable.fromJS({a1: 222}));
}));// ["a", Map]

List 特有查找某个元素

和索引有关的方法,因为list有索引,map有键

  1. indexOf()根据index返回value。lastIndexOf()
  2. findIndex()返回inex,使用方式findIndex(function (val,index,arr){}),有些和findKey()相似。findLastIndex()倒序

查找最大,最小元素

  1. max()可以直接使用,可以传入一个自定义规则的函数
  2. maxBy()可以自定义比较元素和自定义比较规则。
  3. min()
  4. minBy()
// 自定义比较的元素,和比较规则
console.log(Immutable.fromJS([{a: 2}, {a: 1}, {a: 2301}, {a: 222}]).maxBy((value, index, array) => {
    // 自定义比较元素
    return value.get('a');
}, (valueA, valueB) => {
    // 自定义比较规则
    return valueA > valueB;
}).toJS());// {a: 2301}

生成迭代器

keys(),values(),entries() 这几个都会生成迭代器,可以使用for of

  1. 三个分别获取的是
  • 对象键
  • 对象值
  • 对象键值组合[key,value]

截取

  1. slice(start,end)和原生的slice用法一致
  2. rest()返回删除第一个元素后的 List 或者 Map
  3. butLast() 返回删除最后一个元素的 List 或者 Map
  4. skip()从头按照条件抛出number个元素,截取剩余元素
  5. skipLast()从尾按照条件抛出number个元素,截取剩余元素
  6. skipWhile(function (val,index,obj) {})字面意思,当满足条件时,跳。从头开始,需要连续抛出return true的元素,中间断开后,再有return true也不抛出。然后返回剩余元素
  7. skipUntil(function (val,index,obj) {})字面意思,除了什么,其余跳。从头开始,需要连续抛出return false的元素,中间断开后,再有return false也不抛出。然后返回剩余元素。
  8. take()从头开始获取几个元素
  9. takeLast()从尾部开始获取几个元素
  10. takewhile(function (val,index,obj) {})从头开始,获取满足return true的元素
  11. takeUntil()从头开始,获取满足return false的元素

循环遍历

  1. map(function (val,index,array) {})
  2. filter()
  3. every()
  4. some()
  5. forEach()
  6. reduce()作用和原生Array 的 reduce相同
  7. recuceRight()

Map 特有的 mapKeys()/mapEntries()

  1. 对 Map 对象进行处理,返回新的对象
// mapKeys()
Immutable.fromJS({a:5,b:2}).mapKeys((key)=>{
    return key + 'hehe';
})// {ahehe:5,bhehe:2}
// mapEntries() 
Immutable.fromJS({a:5,b:2}).mapEntries(([key,val])=>{
    return [key+'aaa',value+'bbbb'];
})// {aaaa:5bbbb,baaa:2bbbb}

merge

在 Map 类型的中有merge/mergeWithmergeDeep/mergeDeepWidth

  1. 在帖子中,按照两者均有上述方法, 但是文档中 Map 和 List 方法是不同的
// merge 使用方式普通
const one = Map({ a: 10, b: 20, c: 30 })
const two = Map({ b: 40, a: 50, d: 60 })
one.merge(two) // Map { "a": 50, "b": 40, "c": 30, "d": 60 }
// mergeWith 使用的第一个参数是函数
const one = Map({ a: 10, b: 20, c: 30 })
const two = Map({ b: 40, a: 50, d: 60 })
one.mergeWith((oldVal, newVal) => oldVal / newVal, two)// { "a": 0.2, "b": 0.5, "c": 30, "d": 60 }
// 剩余两个只是深度合并

转化成字符串

  • join(separator)

判断是否为空

  • mapObj/listObj.isEmpty()

检查是否有某个key值

  • has()
  • hasIn([path])这个是深度的检测

是否有某个value值

  • includes()
  • contains
  • 这两个方法的参数可以是普通值,可以是 Immutable 中的数据结构

是否是子集

  • isSubSet()判断方法的使用者是不是参数的子集

反转

  • reverse()

排序

  • sort()可以传入参数,自定义排序规则
  • sortBy()可以传入参数,自定义排序关键字和排序规则
console.log(Immutable.fromJS([{a: 1, b: {c: 22}}, {a: 2, b: {c: 22}}, {a: 1, b: {c: 22}},
    {a: 3, b: {c: 22}}, {a: 10, b: {c: 22}}, {a: 9, b: {c: 22}}]).sortBy((value, index, array)=> {
        // 排序关键字 value 就是数组的每一项,然后获取 a 就是依据 a 进行排序
    return value.get('a')
},(a, b) => {
    // -1 是不换位
    if (a < b) {
        return -1;
    }
    if (a > b) {
        // 1 是换位
        return 1;
    }
    if (a === b) {
        return 0;
    }
}).toJS());
// 升序 [{a:1,b:{c:22}},{a: 1, b: {c: 22}},{a: 2, b: {c: 22}}, {a: 3, b: {c: 22}},{a: 9, b: {c: 22}},{a: 10, b: {c: 22}}]

平铺

  • flatten()默认参数值是false,深度平铺.传入参数true,平铺一层
  • 平铺一层时,还有对象没有平铺开,就会显示为对象,Object.还有数组没有平铺开,就会显示为数组 Array
// List
console.log(Immutable.fromJS([1, 2, 3, 4, [1, 11, 111, 12344], {a: 1234, b: {bb: [777, 888]}}, 5, 6]).flatten().toJS());
// [1, 2, 3, 4, 1, 11, 111, 12344, 1234, 777, 888, 5, 6]
console.log(Immutable.fromJS([1, 2, 3, 4, [1, 11, 111, 12344], {a: 1234, b: {bb: [777, 888]}}, 5, 6]).flatten(true).toJS());
// [1, 2, 3, 4, 1, 11, 111, 12344, 1234, Object, 5, 6]

分组

  • groupBy()返回的对象是 OrderedMap.根据自定义规则,选定分组的关键字,然后分组
console.log(Immutable.fromJS([{v: 0, a: 111}, {v: 1, a: {b: [1, 2, 3]}}, {v: 1, a: 333}, {v: 0, a: {b: [1, 2, 3]}}, {v: 1, a: 333}]).groupBy((value) => {
    return value.get('a')
}).toJS());
//  OrderedMap {111: Array[1], 333: Array[2], Map { "b": List [ 1, 2, 3 ] }: Array[2]}
// 含义: 根据 a 的值进行分组。其中,值为 111 的有一个,所以是长度为1的数组。其中第三个是,值为  Map { "b": List [ 1, 2, 3 ] } 的有两个,所以对应长度为2的数组

Map 特有的翻转

  • filp键值翻转,应该保证值是唯一的
console.log(Immutable.fromJS({b: 'b1', a: 'a1', c: 'c1', d: 'd1'}).flip().toJS()); // {b1: "b", a1: "a", c1: "c", d1: "d"}

连接

  • concat()

类型转换

转化成js对象

  • toArray()浅层,转化不了的保留Map或者list
  • toObject()浅层
  • toJS()深层,少用
console.log(Immutable.fromJS([1, 2, 3, 4, 5, 6, {a: {b: [1234, 22]}}]).toArray());// [1, 2, 3, 4, 5, 6, Map]
console.log(Immutable.fromJS([1, 2, 3, 4, 5, 6, [1234, 22]]).toArray());// [1, 2, 3, 4, 5, 6, List]

转化成 Immutable 其他对象

  • toMap()
  • toOrderedMap()
  • toSet()
  • toOrderedSet()
  • toList()
  • toStack()

性能优化,批处理

当使用 push 在 list 上多次操作,会产生多个中间状态的 list,其实只需要最后一个,其他是冗余的。此时可以使用多种解决方式

withMutations

参数是一个函数

const $list1 = Immutable.List.of(1,2,3);
const $list2 = $list1.withMutations(function ($list) {
    $list.push(4).push(5).push(6);
    // 为此 withMutations 函数把list临时变为可变的数据,这三次push实质上只产生了一个中间态list
});
console.log($list1.size);// 3
console.log($list2.size);// 6

asMutable 和 asImmutable

配对使用

  1. 当转换成可变对象的,obj.set()会改变 obj 本身,也会生成一个改变后的对象
  2. 当转换成不可变对象时,obj.set()不会改变 obj 本身,但是会生成一个改变后的对象
const $test1= Immutable.List.of(1,2,3);
const $test2 = $test1.asMutable(); // $test2 变成可变对象
console.log($test1 === $test2); // false
console.log(Immutable.is($test1,$test2)); //true

// 当可变对象改变的时候
const $test3 = $test2.set(0,123);
console.log($test3 === $test2);//true
console.log(Immutable.is($test3,$test2));// true


// 转变成不可变的对象
const $test4 = $test3.asImmutable();
console.log($test3 === $test4);//true
console.log(Immutable.is($test3,$test4));// true
const $test5 = $test4.set(0,234);
console.log($test4 === $test5);//true
console.log(Immutable.is($test4,$test5));// true

相关文章

网友评论

      本文标题:02基础操作

      本文链接:https://www.haomeiwen.com/subject/efhmpxtx.html