2015-03-18 17 views

Odpowiedz

39

Zasadniczo nie: jesteś wykonywania listy odnośnika przez wartość, nie przez indeks, więc zawsze będzie przesuw liniowy.

Poprawa byłoby użyć find zamiast filter:

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

Ach, miło, próbowałem tego, ale nie udało mi się, nie mam już po co. Ale to bardziej precyzyjne. Dzięki! – sspross

+0

To również działa dla List. Dzięki. – Lebul

-2

Czy istnieje już sposób ów łatwiej? Nie wiem ale możesz napisać własną funkcję. Coś jak to powinno działać:

var myFunc = function(id){ 

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

    return object; 
} 

Wtedy po prostu zrobić:
var myObj = myFunc(4);

+1

tak dobre, że to prawda, ale to nie o to chodzi. może masz rację i nie ma "łatwiejszego" sposobu. Miałem nadzieję, że przegapiłem jakiś punkt w niezmiennej dokumentacji :) – sspross

+0

@sspross, nie byłem pewien, czy to by było to, co chciałeś. To było moje najlepsze przypuszczenie biorąc pod uwagę, że w rzeczywistości nie używałem Immutable (miałem nadzieję, że po prostu chciałeś ogólnego rozwiązania JS). – Jakar

10

Pierwszą rzeczą, aby pamiętać, że nie jesteś w rzeczywistości stworzenie mapy, tworzysz listę:

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

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

Aby utworzyć mapę, można użyć argumentu reviver w swoim zgłoszeniu toJS (docs), ale z pewnością nie jest to najbardziej intuicyjny interfejs API, alternatywnie można zrobić coś takiego:

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

Teraz mamy odpowiednią mapę Immutable.js który posiada metodę get

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

To może być ważne, aby zagwarantować porządek tablicy. Jeśli tak jest w przypadku:

  1. Użyć OrderedMap
  2. Czy metodę nastawioną na OrderedMap w każdej iteracji swojej tablicy źródłowej

Poniższy przykład używa „withMutations” dla lepszej wydajności.

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

Podczas korzystania z JS dla tablicy, otrzymasz List nie map. Będzie lepiej i łatwiej, jeśli utworzysz mapę. Poniższy kod przekształci wynik w mapę niezmienną.

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

Teraz można

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

Uwaga, jeśli wynik jest zagnieżdżone struktury i jeśli to ma tablicę, to będzie lista z powyższym kodzie.

2

Z ES2015 składni (i stałych):

const result = map.find(o => o.get('id') === 4); 
Powiązane problemy