晴明的博客园 GitHub      CodePen      CodeWars     

[js] Immutable

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

List可以使用部分与原本Array同名的方法

map

    var map1 = Immutable.Map({a: 1, b: 3});
    var map2 = map1.set('a', 2);

    console.log(map1.get('a')); // 1
    console.log(map2.get('a')); // 2
    // 1. Map 大小
    const map1 = Immutable.Map({ a: 1 });
    console.log(map1.size)
    // => 1

    // 2. 新增或取代 Map 元素
    // set(key: K, value: V)
    const map2 = map1.set('a', 5);
    console.log(map2.get('a'))//5
    console.log(map2.toJS())
    // => Map { "a": 5 }

    // 3. 删除元素
    // delete(key: K)
    const map3 = map1.delete('a');
    console.log(map3.size)//0
    console.log(map3.toJS())
    // => Map {}

    // 4. 清除 Map 內容
    const map4 = map1.clear();
    console.log(map4.size)//0
    console.log(map4.toJS())
    // => Map {}

    // 5. 更新 Map 元素
    // update(updater: (value: Map<K, V>) => Map<K, V>)
    // update(key: K, updater: (value: V) => V)
    // update(key: K, notSetValue: V, updater: (value: V) => V)
    const map5 = map1.update('a', () => (7))
    console.log(map5.get('a'))//7
    console.log(map5.toJS())
    // => Map { "a": 7 }

    // 6. 合并 Map
    const map6 = Immutable.Map({ b: 3 });
    map1.merge(map6);
    console.log(map1.toJS())
    console.log(map6.toJS())
    // => Map { "a": 1, "b": 3 }

List

    const List= Immutable.List;

    // 1. 取得 List 长度
    const arr1 = List([1, 2, 3]);
    console.log(arr1.size)
    // => 3

    // 2. 新增或取代 List 元素內容
    // set(index: number, value: T)
    // 将index 位置的元素替换
    const arr2 = arr1.set(-1, 7);
    console.log(arr2.toJS())
    // => [1, 2, 7]
    const arr3 = arr1.set(4, 0);
    console.log(arr3.toJS())
    // => [1, 2, 3, undefined, 0]

    // 3. 删除 List 元素
    // delete(index: number)
    // 删除 index 位置的元素
    const arr4 = arr1.delete(1);
    console.log(arr4.toJS())
    // => [1, 3]

    // 4. 插入元素到 List
    // insert(index: number, value: T)
    // 在 index 位置插入 value
    const arr5 = arr1.insert(1, 8);
    console.log(arr5.toJS())
    // => [1, 8, 2, 3]

    // 5. 清空 List
    // clear()
    const arr6 = arr1.clear();
    console.log(arr6.toJS())
    // => []

Set

    const Set = Immutable.Set;

    // 1. 建立 Set
    const set1 = Set([1, 2, 3]);
    console.log(set1.toJS());
    // => Set { 1, 2, 3 }

    // 2. 新增元素
    const set2 = set1.add(1).add(5);
    console.log(set2.toJS());
    // => Set { 1, 2, 3, 5 }
    // 由于 Set 为不能重复集合,故 1 只能出现一次

    // 3. 刪除元素
    const set3 = set1.delete(3);
    console.log(set3.toJS());
    // => Set { 1, 2 }

    // 4. 取合集
    const set4 = Set([2, 3, 4, 5, 6]);
    console.log(set1.union(set4).toJS());
    // => Set { 1, 2, 3, 4, 5, 6 }

    // 5. 取交集
    console.log(set1.intersect(set4).toJS());
    // => Set { 2, 3 }

    // 6. 取差集
    console.log(set1.subtract(set4).toJS());
    // => Set { 1 }
    console.log(set4.subtract(set1).toJS());
    // => Set { 6, 5, 4}

Structural Sharing

    const obj = {
        count: 1,
        list: [1, 2, 3, 4, 5]
    }
    var map1 = Immutable.fromJS(obj);
    var map2 = map1.set('count', 4);

    console.log(map1.list === map2.list); // true

Support Lazy Operation

    let l = Immutable.Range(1, Infinity)
            .map(n => -n)
    //? Error: Cannot perform this action with an infinite size.
    console.log(l)//n {size: Infinity}

    let z =  Immutable
            .Range(1, Infinity)
            .map(n => -n)
            .take(2)
            .reduce((r, n) => r + n, 0);
    // -3
    console.log(z)

react 性能优化

    console.log({ foo: 'app' }==={ foo: 'app' })//false

    var SomeRecord = Immutable.Record({ foo: null });
    var x = new SomeRecord({ foo: 'app'  });
    var y = x.set('foo', 'app');
    console.log(x === y); // true
// 原来的写法
let foo = {a: {b: 1}};
let bar = foo;
bar.a.b = 2;
console.log(foo.a.b);  // 打印 2
console.log(foo === bar);  //  打印 true

// 使用 immutable.js 后
import Immutable from 'immutable';
foo = Immutable.fromJS({a: {b: 1}});
bar = foo.setIn(['a', 'b'], 2);   // 使用 setIn 赋值
console.log(foo.getIn(['a', 'b']));  // 使用 getIn 取值,打印 1
console.log(bar.getIn(['a', 'b'])); //2
console.log(foo === bar);  //  打印 false

Iterable

The Iterable is a set of (key, value) entries which can be iterated, and is the base class for all collections in immutable, allowing them to make use of all the Iterable methods (such as map and filter).
class Iterable<K, V>

Discussion

Note: An iterable is always iterated in the same order, however that order may not always be well defined, as is the case for the Map and Set.

Conversion to JavaScript types

toJS()

Deeply converts this Iterable to equivalent JS.
toJS(): any
alias
toJSON()
Discussion

Iterable.Indexeds, and Iterable.Sets become Arrays, while Iterable.Keyeds become Objects.

Reading values

get()

Returns the value associated with the provided key, or notSetValue if the Iterable does not contain this key.
get(key: K, notSetValue?: V): V
Discussion

Note: it is possible a key may be associated with an undefined value, so if notSetValue is not provided and this method returns undefined, that does not guarantee the key was not found.

getIn()

Returns the value found by following a path of keys or indices through nested Iterables.

getIn(searchKeyPath: Array<any>, notSetValue?: any): any
getIn(searchKeyPath: Iterable<any, any>, notSetValue?: any): any


Map

Immutable Map is an unordered Iterable.Keyed of (key, value) pairs with O(log32 N) gets and O(log32 N) persistent sets.
class Map<K, V> extends Collection.Keyed<K, V>
Discussion

Iteration order of a Map is undefined, however is stable. Multiple iterations of the same Map will iterate in the same order.

Map's keys can be of any type, and use Immutable.is to determine key equality. This allows the use of any value (including NaN) as a key.

Because Immutable.is returns equality based on value semantics, and Immutable collections are treated as values, any Immutable collection may be used as a key.

Map().set(List.of(1), 'listofone').get(List.of(1));
// 'listofone'

Any JavaScript object may be used as a key, however strict identity is used to evaluate key equality. Two similar looking objects will represent two different keys.

Implemented by a hash-array mapped trie.

Construction

Map()

Creates a new Immutable Map.

Map<K, V>(): Map<K, V>
Map<K, V>(iter: Iterable.Keyed<K, V>): Map<K, V>
Map<K, V>(iter: Iterable<any, Array<any>>): Map<K, V>
Map<K, V>(array: Array<Array<any>>): Map<K, V>
Map<V>(obj: {[key: string]: V}): Map<string, V>
Map<K, V>(iterator: Iterator<Array<any>>): Map<K, V>
Map<K, V>(iterable: Object): Map<K, V>

Discussion

Created with the same key value pairs as the provided Iterable.Keyed or JavaScript Object or expects an Iterable of [K, V] tuple entries.

var newMap = Map({key: "value"});
var newMap = Map([["key", "value"]]);

Keep in mind, when using JS objects to construct Immutable Maps, that JavaScript Object properties are always strings, even if written in a quote-less shorthand, while Immutable Maps accept keys of any type.

var obj = { 1: "one" };
Object.keys(obj); // [ "1" ]
obj["1"]; // "one"
obj[1];   // "one"

var map = Map(obj);
map.get("1"); // "one"
map.get(1);   // undefined

Property access for JavaScript Objects first converts the key to a string, but since Immutable Map keys can be of any type the argument to get() is not altered.


fromJS()

Deeply converts plain JS objects and arrays to Immutable Maps and Lists.

fromJS(json: any, reviver?: (k: any, v: Iterable<any, any>) => any): any
Discussion

If a reviver is optionally provided, it will be called with every collection as a Seq (beginning with the most nested collections and proceeding to the top-level collection itself), along with the key refering to each collection and the parent JS object provided as this. For the top level, object, the key will be "". This reviver is expected to return a new Immutable Iterable, allowing for custom conversions from deep JS objects.

This example converts JSON to List and OrderedMap:

Immutable.fromJS({a: {b: [10, 20, 30]}, c: 40}, function (key, value) {
  var isIndexed = Immutable.Iterable.isIndexed(value);
  return isIndexed ? value.toList() : value.toOrderedMap();
});

// true, "b", {b: [10, 20, 30]}
// false, "a", {a: {b: [10, 20, 30]}, c: 40}
// false, "", {"": {a: {b: [10, 20, 30]}, c: 40}}

If reviver is not provided, the default behavior will convert Arrays into Lists and Objects into Maps.

reviver acts similarly to the same parameter in JSON.parse.

Immutable.fromJS is conservative in its conversion. It will only convert arrays which pass Array.isArray to Lists, and only raw objects (no custom prototype) to Map.

Keep in mind, when using JS objects to construct Immutable Maps, that JavaScript Object properties are always strings, even if written in a quote-less shorthand, while Immutable Maps accept keys of any type.

var obj = { 1: "one" };
Object.keys(obj); // [ "1" ]
obj["1"]; // "one"
obj[1];   // "one"

var map = Map(obj);
map.get("1"); // "one"
map.get(1);   // undefined

Property access for JavaScript Objects first converts the key to a string, but since Immutable Map keys can be of any type the argument to get() is not altered.
"Using the reviver parameter"

posted @ 2016-08-09 16:35  晴明桑  阅读(438)  评论(0编辑  收藏  举报