2016-12-07 5 views
0

У меня есть данные, которые поступают в следующем формате как action.places.Установите пользовательские ключи immutablejs для предотвращения дублирования данных?

Я хотел бы объединить это только с новыми данными и вернуться к новой карте обновленных мест. Если я получаю объект мест, и одно из мест имеет тот же lat/lon, что и в предыдущем месте, я не хочу добавлять эти данные.

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

Как бы это сделать с помощью карты? В настоящее время я, добавляя таким образом, но все дублируется, я не могу найти нон беспорядочный решение:

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

В идеале я бы установить ключ каждого OBJ в [${lat},${lon}] (только единственным способом для идентификации место), таким образом мне нужно будет только перебирать ключи, чтобы получить мои места.

+0

Основываясь на этом описании, я считаю, что вам следует использовать 'Set' вместо' List' для хранения «мест». – Josep

+0

Я использую «карту». @Josep - я обновил вопрос. – eveo

+0

Нет, это не так. На верхнем уровне вы находитесь, но «места» - это список, это потому, что 'fromJS' по умолчанию преобразует массив в список. – Josep

ответ

1

вы можете отфильтровать повторяющиеся элементы места

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

Как использовать клавиши lat и lon? Этот способ кажется немного запутанным. – eveo

+0

@eveo вы можете это сделать, но u меняют схему данных, и решение, которое я дал, не менее эффективно. –

+0

вы дали мне идентичное решение по моей предыдущей проблеме, сейчас я использую другой подход, так что очевидно, что схема изменится. – eveo

0

Если вы используете Immutable.Set вместо Immutable.List для сохраняющихся мест, то все было бы проще, и все будет работать лучше.

Таким образом, если в вашем редукторе вы сделали что-то вроде:

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

Вы должны быть хорошо.

Дайте мне знать, если это сработает для вас.

+0

Я не получаю 'places => places.merge()'. У меня нет доступа к таким местам, но action.places. Также в initialState, зачем заключать в квадратные скобки?Почему бы не 'places: new Set()'. Также я возвращаю состояние и устанавливаю другие вещи в состоянии, поэтому он также должен быть в комплекте. – eveo

+0

В коде, который я предоставил, я деструктурировал действие, в параметрах, обратите внимание на конец этой строки 'const yourReducer = (state = initialState, {type, places})'? Это деструктуризация ES6. Если вы посмотрите документацию «Immutable.Map», вы заметите, что при инициализации новой Карты вы должны передать массив с кортежами. Каждый кортеж должен иметь ключ в первой позиции и значение во второй позиции. – Josep

+0

Ах, хорошо да, имеет смысл. Я все еще не понимаю. Я делаю 'action.places => action.places.merge (Set (fromJS (action.places)))' Whaaaaat? – eveo