如何通过值从不可变的js映射中获取特定对象?

时间:2015-03-18 13:57:02

标签: javascript immutability

我从对象列表中创建了一个不可变的映射(带有Immutable-JS):

var result = [{'id': 2}, {'id': 4}];
var map = Immutable.fromJS(result);

现在我想用id = 4获取对象。

是否有比这更简单的方法:

var object = map.filter(function(obj){
 return obj.get('id') === 4
}).first();

6 个答案:

答案 0 :(得分:51)

基本上,不是:您按值而不是按索引执行列表查找,因此它始终是线性遍历。

改进是使用find代替filter

var result = map.find(function(obj){return obj.get('id') === 4;});

答案 1 :(得分:12)

首先要注意的是,您实际上并未创建地图,而是要创建一个列表:

var result = [{'id': 2}, {'id': 4}];
var map = Immutable.fromJS(result);

Immutable.Map.isMap(map); // false
Immutable.List.isList(map); // true

要创建地图,您可以在reviver来电(docs)中使用toJS参数,但它肯定不是最直观的API,或者您可以做类似的事情:

// lets use letters rather than numbers as numbers get coerced to strings anyway
var result = [{'id': 'a'}, {'id': 'b'}];
var map = Immutable.Map(result.reduce(function(previous, current) { 
    previous[ current.id ] = current;
    return previous;
}, {}));

Immutable.Map.isMap(map); // true

现在我们有一个正确的Immutable.js地图,它有一个get方法

var item = Map.get('a'); // {id: 'a'}

答案 2 :(得分:4)

保证数组的顺序可能很重要。如果是这样的话:

  1. 使用OrderedMap
  2. 在源数组的每次迭代中对OrderedMap执行set方法
  3. 以下示例使用" withMutations"为了更好的表现。

    var OrderedMap = Immutable.OrderedMap
    
    
    // Get new OrderedMap
    function getOm(arr) {
        return OrderedMap().withMutations(map => {
            arr.forEach(item => map.set(item.id, item))
        })
    }
    
    // Source collection
    var srcArray = [
        {
            id: 123,
            value: 'foo'
        },
        {
            id: 456,
            value: 'bar'
        }
    ]
    
    
    var myOrderedMap = getOm(srcArray)
    
    myOrderedMap.get(123)
    // --> { id: 123, value: 'foo' }
    
    myOrderedMap.toObject()
    // --> { 123: {id: 123, value: 'foo'}, 456: {id: 456, value: 'bar'} }
    
    myOrderedMap.toArray()
    // --> [ {id: 123, value: 'foo'}, { id: 456, value: 'bar' } ]
    

答案 3 :(得分:4)

使用fromJS作为数组时,您将获得List not map。如果您创建地图将会更好,更容易。以下代码将结果转换为Immutable地图。

  const map = result.reduce((map, json) =>
    map.set(json.id, Immutable.fromJS(json))
  , Map());

现在,你可以

   map.get('2');   //{'id': 2}

注意,如果结果具有嵌套结构,并且如果有数组,则它将是带有上述代码的List。

答案 4 :(得分:3)

使用 ES2015语法(和常量):

SELECT ratings

答案 5 :(得分:-2)

是否已经有一种方法更容易了?我不知道。但你可以编写自己的函数。这样的事情应该有效:

var myFunc = function(id){

    var object = map.filter(function(obj){return obj.get('id') === id}).first();

    return object;
}

然后你会这样做:
var myObj = myFunc(4);