2015-03-18 4 views
30

Я создал непреложную карту (с Immutable-JS) из списка объектов:Как получить определенный объект из неизменяемой 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(); 

ответ

39

По существу, нет: вы выполняете поиск списка по значению, а не по индексу, так что всегда будет линейный обход.

Улучшение было бы использовать find вместо filter:

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

Ах, хорошо, я пробовал это, но не смог, не знаю почему. Но это более точно \t. Благодаря! – sspross

+0

Это также работает для List. Благодарю. – Lebul

-2

Есть ли уже способ тот легче? Я не знаю. но вы можете написать свою собственную функцию. Нечто подобное должно работать:

var myFunc = function(id){ 

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

    return object; 
} 

Тогда вы бы просто сделать:
var myObj = myFunc(4);

+1

да нормально, что это правда, но это не главное. возможно, вы правы, и нет «более простого» способа. Я надеялся, что пропустил какой-то момент в документах Immutable :) – sspross

+0

@sspross, я не был уверен, что это будет то, что вы хотели. Это было мое лучшее предположение, учитывая, что я на самом деле не использовал Immutable (надеялся, что вам просто нужен общий JS-решение). – Jakar

10

Первое, что нужно отметить, что вы на самом деле не создает карту, вы создаете список:

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

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

Чтобы создать карту, вы можете использовать аргумент reviver в своем toJS звоните (docs), но это, конечно, не самый интуитивный 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'} 
4

Это может быть важно, чтобы гарантировать порядок массива. Если это так:

  1. Используйте OrderedMap
  2. ли метод набора на OrderedMap на каждой итерации исходного массива

В приведенном ниже примере используется «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

При использовании функцииJS для массива вы получите список не map. Это будет лучше и проще, если вы создадите карту. Следующий код преобразует результат в неизменяемую карту.

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

Теперь вы можете

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

Обратите внимание, если результат имеет вложенные структуры, и если это имеет массив, это будет список с указанным кодом.

2

С ES2015 синтаксиса (и константы):

const result = map.find(o => o.get('id') === 4); 
Смежные вопросы