2016-12-07 4 views
0

Ich habe Daten, die im folgenden Format als action.places kommt.Legen Sie benutzerdefinierte immutablejs-Schlüssel fest, um Datenduplizierung zu verhindern?

Ich möchte dies nur mit neuen Daten kombinieren und eine neue Karte der aktualisierten Orte zurückgeben. Wenn ich ein Objekt von Orten bekomme und einer der Orte den gleichen Breitengrad wie ein vorheriger Ort hat, möchte ich diese Daten nicht anhängen.

{ 
    places: [ 
    { 
     place: { 
     lat: 123, 
     lon: 321, 
     } 
    }, 
    { 
     place: { 
     lat: 432, 
     lon: 234, 
     } 
    }, 
    ] 
} 

Wie würde ich das mit einer Karte machen? Derzeit bin anhängen ich auf diese Weise aber alles doppelt vorhanden ist, kann ich nicht eine nicht unordentlich Lösung finden:

case RECEIVE_PLACES: 
    return state 
    .set('places', state.get('places').update(fromJS(action.places))) 

Im Idealfall würde ich den Schlüssel gesetzt jedes OBJ [${lat},${lon}] (nur auf einzigartige Weise ein zu identifizieren Platz), auf diese Weise würde ich nur über die Schlüssel iterieren müssen, um meine Plätze zu bekommen.

+0

Basierend auf dieser Beschreibung denke ich, dass Sie eine "Set" anstelle einer "Liste" zum Speichern der "Orte" verwenden sollten. – Josep

+0

Ich benutze eine 'Map'. @Josep - Ich habe die Frage aktualisiert. – eveo

+0

Nein, du bist nicht. Auf der obersten Ebene sind Sie, aber "Orte" ist eine Liste, weil "fromJS" standardmäßig ein Array in eine Liste konvertiert. – Josep

Antwort

1

Sie können die wiederholten Ort Artikel herauszufiltern

case RECEIVE_PLACES: { 
    const newPlaces = fromJS(action.places).filter((newItem) => (
    !state.get('stores').find((oldItem) => (
     oldItem.place.lat === newItem.place.lat && 
     oldItem.place.lon === newItem.place.lon 
    ) 
); 

    return state.set('stores', state.get('stores').update(newPlaces)); 
} 
+0

Was ist mit der Verwendung der Lat und Lon als Schlüssel? Dieser Weg scheint etwas verworren. – eveo

+0

@eveo Sie können das tun, aber Sie ändern das Schema der Daten und die Lösung, die ich gab, ist nicht weniger in der Leistung. –

+0

Sie gaben mir eine identische Lösung für mein vorheriges Problem, ich nehme jetzt einen anderen Ansatz, also wird sich das Schema offensichtlich ändern. – eveo

0

Wenn Sie eine Immutable.Set anstelle eines Immutable.List für persistierende die Plätze benutzen dann wäre alles einfacher sein und die Dinge würden besser.

Also, wenn in Ihrem Minderer Sie so etwas wie tat:

import { Map, Set, fromJS } from 'immutable'; 

const initialState = new Map([ 
    ['places', new Set()], 
    // Whatever other props that Map has 
]); 

const yourReducer = (state = initialState, { type, places }) => { 
    switch (type) { 
    RECEIVE_PLACES: 
     return state.update('places', places => places.merge(
     new Set(fromJS(places)) 
    ); 
    default: 
     return state; 
    } 
}; 

Sie sollten in Ordnung sein.

Lassen Sie mich wissen, ob dies für Sie funktioniert.

+0

Ich bekomme 'places => places.merge()' nicht. Ich habe keinen Zugang zu "Orten", sondern zu action.places. Warum auch in initialState in eckige Klammern fassen?Warum nicht 'places: new Set()'. Auch ich gebe Zustand zurück und setze andere Dinge im Zustand, also muss es innerhalb eines Satzanrufs auch sein. – eveo

+0

In dem Code, den ich zur Verfügung gestellt habe, habe ich die Aktion de-strukturiert, in den Parametern notiere das Ende dieser Zeile 'const yourReducer = (state = initialState, {type, places})'? Das ist ES6-Destrukturierung. Wenn Sie sich die Dokumentation von 'Immutable.Map' anschauen, werden Sie feststellen, dass Sie beim Initialisieren einer neuen Map ein Array mit Tupeln übergeben sollten. Jedes Tupel sollte den Schlüssel in der ersten Position und den Wert in der zweiten Position haben. – Josep

+0

Ah okay, macht ja Sinn. Ich verstehe es immer noch nicht. Tue ich action.places => action.places.merge (Set (fromJS (action.places))) 'Whaaaaat? – eveo

Verwandte Themen