世间自有公道,付出总有回报,说到不如做到,要做就做好,步步高!

【译】Immutable.js: Map - 5

Immutable's Map与JavaScript对象很相似,但是如果你不知道它是如何工作的话,它可能会严重地影响你。这篇文章是第一次深入了解Immutable Maps,向您展示如何以正确的方式使用它们。

认识认识 Immutable 中的Map

一个不可变映射是键/值对的无序集合,乍一看似乎与JavaScript对象相似。但是,它具有以下附加属性:

  1. 您可以迭代Map中的键
  2. 迭代的键的顺序不会改变(尽管你不知道什么顺序会提前)
  3. 所有的键都被转换成字符串。
  4. 一个键可以是任何类型的 - 甚至是NaN和一个数组
  5. 如果Immutable.is(map1,map2)返回true,则两个映射是相同的
  6. 一个不可变的集合(例如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中获取,设置,更新和删除。

posted @ 2017-12-18 08:56  疯狂秀才  阅读(1187)  评论(0编辑  收藏  举报