【译】Immutable.js: Map - 5
Immutable's Map与JavaScript对象很相似,但是如果你不知道它是如何工作的话,它可能会严重地影响你。这篇文章是第一次深入了解Immutable Maps,向您展示如何以正确的方式使用它们。
认识认识 Immutable 中的Map
一个不可变映射是键/值对的无序集合,乍一看似乎与JavaScript对象相似。但是,它具有以下附加属性:
- 您可以迭代Map中的键
- 迭代的键的顺序不会改变(尽管你不知道什么顺序会提前)
- 所有的键都被转换成字符串。
- 一个键可以是任何类型的 - 甚至是NaN和一个数组
- 如果Immutable.is(map1,map2)返回true,则两个映射是相同的
- 一个不可变的集合(例如List,Map,Seq等)可以是一个Key
Create an empty Map
// Empty Map:
const map = Immutable.Map();
// Output:
map;
Create a populated Map of data
您可以使用Map()
构造函数或Map.of()
方法根据现有数据创建Map,具体取决于您用于创建Map的数据类型:
Map.of()
从一组函数参数中创建Map时使用,每对参数都被解释为一个键和一个值;Map()
使用其他方式创建Map时使用。
Create a new Map from…
…a JavaScript Array
要从数组创建一个新的Map,实际上需要一个数组中的数组,每个数组项都是一个元组(即有两个值)。每个数组项的第一个值将被用作MAP中的一个键,第二个项将是它的值。
// New Map from JavaScript array
const avengersArray = [
['heroName1', 'ironMan'],
['heroName2', 'captainAmerica']
];
const avengersMap = Immutable.Map(avengersArray);
// Output:
avengersMap;
{
heroName1: "ironMan",
heroName2: "captainAmerica"
}
重要提示:请记住,密钥名称必须是唯一的。尝试在上面的代码中将“heroName2”更改为“heroName1”,看看会发生什么。这是因为不可变将覆盖它看作是一个重复的密钥。
…a JavaScript Object
// New Map from JavaScript object
const avengersObj = {
ironMan: 'Tony Stark',
captainAmerica: 'Steve Rogers'
};
const avengersMap = Immutable.Map(avengersObj);
// Output:
{
captainAmerica: "Steve Rogers",
ironMan: "Tony Stark"
}
...深度嵌套的JavaScript对象或JSON编码的数据
Immutable的Map
不能在深度嵌套的对象上工作,因为它只会进行浅转换(例如,obj.key
中的键将被转换为Map,但obj.key.subkey
中的子键将保持不变 - 也就是说,如果subkey
是一个JavaScript对象,它将保持一个JavaScript对象,而不是一个不可变的映射)。
为了从一个复杂的对象或JSON编码的数据创建一个新的Map,因此,您需要使用fromJS()。
// New Map from deeply nested JavaScript object
const avengers = {
hero1: {
ironMan: {
realName: 'Tony Stark'
}
},
hero2: {
captainAmerica: {
realName: 'Steve Rogers'
}
}
};
// Create the Map
const avengersMap = Immutable.Map(Immutable.fromJS(avengers));
// Test that we have a deeply nested Map
const ironMan = avengersMap.getIn(['hero1', 'ironMan']);
// Output:
Immutable.Map.isMap(ironMan);
尝试从上面的代码中删除Immuable.fromJS,你应该看到输出转为false。这是因为,如果没有fromJS(),深层嵌套的对象将不会被转换为一个Map。
…a set of function arguments
您可以从任意数量的函数参数创建一个Map,每个参数对被解释为一个键/值对。只要记住用Map.of()
创建你的Map
// New Map from function arguments
const avengersMap = Immutable.Map.of(
'ironMan', 'Tony Stark', 'captainAmerica', 'Steve Rogers'
);
// Output:
avengersMap;
…a JavaScript iterator
可以使用内置的(例如一个数组)或用户定义的任何ES6可迭代对象来创建一个新的不可变映射。
// New Map from existing JavaScript iterator (Array.map example)
// Note: an ES6 object is not an iterator, so we'll use an array instead
const avengersArray = ['ironMan' , 'captainAmerica'];
const avengersMap = Immutable.Map(avengersArray.map(
(item, index) => ([ 'heroName' + index, item ])));
// Output:
avengersMap;
…an Immutable List
就像从数组创建Map一样,List必须包含List列表,每个List项都是一个元组,它将被Map用作键/值对。
// New Map from existing List
const avengersList = Immutable.List([['heroName1', 'ironMan'], ['heroName2', 'captainAmerica']]);
const avengersMap = Immutable.Map(avengersList);
// Output:
avengersMap;
{
heroName1: "ironMan",
heroName2: "captainAmerica"
}
…an Immutable Map
// New Map from existing Map
const avengersMap = Immutable.Map({
hero1: 'ironMan',
hero2: 'captainAmerica',
hero3: 'blackWidow'
});
const newAvengersMap = Immutable.Map(avengersMap);
// Output:
newAvengersMap;
{
hero1: "ironMan",
hero2: "captainAmerica",
hero3: "blackWidow"
}
…other Immutable objects
您可以使用任何不可变对象创建新的Map,其中包括:
- List
- Map
- OrderedMap
- Set
- OrderedSet
- Stack
- Record
OrderedMap
一个OrderedMap和Map一样,但是保证迭代的键顺序总是一样的。您可以使用Map执行的其他操作,OrderedMap也可以使用。
请注意,OrderedMap比Map更慢,所以如果你不关心被迭代的键的顺序,可以使用Map。
Get, Set, Update and Delete Map properties
如你所看到的,创建地图可能会非常复杂。一旦创建,他们提供了一个强大的方式来执行数据操作。本系列的下一篇文章将介绍如何从Map中获取,设置,更新和删除。