web-dev-qa-db-fra.com

Comment obtenir un objet spécifique d'une carte js immuable par valeur?

J'ai créé une carte immuable (avec Immutable-JS ) à partir d'une liste d'objets:

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

Maintenant, je veux obtenir l'objet avec id = 4.

Y a-t-il un moyen plus facile que cela:

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

Essentiellement, non: vous effectuez une recherche de liste par valeur, et non par index, il s'agira donc toujours d'un parcours linéaire.

Une amélioration consisterait à utiliser find au lieu de filter:

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

La première chose à noter est que vous ne créez pas réellement une carte, vous créez une liste:

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

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

Pour créer une carte, vous pouvez utiliser un argument reviver dans votre appel toJS ( docs ), mais ce n’est certainement pas l’application la plus intuitive, sinon vous pouvez le faire. quelque chose comme:

// 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

Maintenant, nous avons une carte Immutable.js appropriée qui a une méthode get

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

Il peut être important de garantir l’ordre du tableau. Si c'est le cas:

  1. Utiliser une carte commandée
  2. Faites une méthode set sur OrderedMap à chaque itération de votre tableau source

L'exemple ci-dessous utilise "withMutations" pour de meilleures performances.

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
eezing

Si vous utilisez fromJS pour array, vous obtiendrez une liste non mappée. Ce sera mieux et plus facile si vous créez une carte. Le code suivant convertira le résultat en mappage immuable.

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

Maintenant vous pouvez

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

Notez que si le résultat a une structure imbriquée et si cela a un tableau, ce sera une liste avec le code ci-dessus.

4
Anand Dayalan

Avec syntaxe ES2015 (et constantes):

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