Подтвердить что ты не робот

Как получить определенный объект из неизменяемой js-карты по значению?

Я создал неизменяемую карту (с 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();
4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

Возможно, важно гарантировать порядок массива. Если это случай:

  • Использовать OrderedMap
  • Сделайте метод set на 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' } ]

Ответ 4

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

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

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

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

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

Ответ 5

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

const result = map.find(o => o.get('id') === 4);

Ответ 6

Есть ли способ, который проще? Я не знаю. но вы можете написать свою собственную функцию. Что-то вроде этого должно работать:

var myFunc = function(id){

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

    return object;
}

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