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

Javascript 如何通过值从不可变的js映射中获取特定对象?,javascript,immutability,Javascript,Immutability,我从对象列表中创建了一个不可变的映射(使用): 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(); 有没有更简单的方法?我不知道。但是您可以编写自己的函数。像这样的方法应该会奏效: var

我从对象列表中创建了一个不可变的映射(使用):

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();

有没有更简单的方法?我不知道。但是您可以编写自己的函数。像这样的方法应该会奏效:

var myFunc = function(id){

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

    return object;
}
那么您只需执行以下操作:

var myObj=myFunc(4)

本质上,否:您正在按值而不是按索引执行列表查找,因此它将始终是线性遍历

一个改进是使用
find
而不是
filter

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

首先要注意的是,您实际上不是在创建地图,而是在创建列表:

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

Immutable.Map.isMap(map); // false
Immutable.List.isList(map); // true
为了创建映射,您可以在
toJS
call()中使用
reviver
参数,但它肯定不是最直观的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'}

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

  • 使用OrderedMap
  • 在源数组的每次迭代中对OrderedMap执行set方法
  • 下面的示例使用“WithTranslations”以获得更好的性能

    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' } ]
    

    当使用fromJS作为数组时,您将得到列表而不是映射。如果你创建一张地图,它会更好更容易。下面的代码将结果转换为不可变映射

      const map = result.reduce((map, json) =>
        map.set(json.id, Immutable.fromJS(json))
      , Map());
    
    现在,你可以

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

    注意,如果结果具有嵌套结构,并且具有数组,则它将是一个包含上述代码的列表。

    带有ES2015语法(和常量):


    是的,没错,但这不是重点。也许你是对的,没有“更简单”的方法。我希望我错过了不可变文档中的一些要点:)@sspross,我不确定这是否是您想要的。这是我最好的猜测,因为我没有实际使用Immutable(希望您只是想要一个通用的JS解决方案)。这不是op要求的ImmutableJS。@AndrewMcLagan这不是与公认的答案完全相同,语法不同吗?
    const result = map.find(o => o.get('id') === 4);