Как я могу войти в модель, чтобы изменить некоторые вложенные значения

Я хочу изменить некоторые глубоко вложенные значения внутри моей модели.

type alias Tone = ( String, Int )

type alias Fret =
    {   number : Int
    ,   tone : Tone
    ,   active : Bool
    }

type alias GuitarString =
    {   number : Int
    ,   frets : List Fret
    }

Моя модель называется "Гриф":

type alias Fretboard =
    {   guitarStrings : List GuitarString
    }

Как изменить значение активного поля внутри определенного лада?

Иерархия такова:

Fretboard > GuitarStrings > Frets

Спасибо.


elm
person Timo    schedule 11.08.2017    source источник


Ответы (1)


В вашей модели у вас есть несколько списков, и вам нужно будет указать, какой элемент в списке следует обновить. Пакет elm-community/list-extra имеет несколько хороших хелперов для обновления значения в списке, некоторые по условию, а другие по указанию индекса.

В этом примере я использую updateIf для проверки номера строки, хранящегося в .number файла GuitarString. Это, вероятно, будет хорошо, но это означает, что вы должны будете нести ответственность за то, чтобы номер существовал и существовал только один раз в этом списке. Вы также можете обновить индекс, используя updateIfIndex; это просто зависит от того, как вы обычно обрабатываете их в своем приложении.

Вот примерный набор функций обновления для ваших нужд, использующий только пакет elm-community/list-extra в качестве зависимости.

setGuitarActiveFretTone : Int -> Tone -> Fretboard -> Fretboard
setGuitarActiveFretTone string tone fb =
    { fb
        | guitarStrings =
            updateIf
                (\gs -> gs.number == string)
                (setActiveFretTone tone)
                fb.guitarStrings
    }

setActiveFretTone : Tone -> GuitarString -> GuitarString
setActiveFretTone tone gs =
    { gs | frets = updateIf .active (setTone tone) gs.frets }

setTone : Tone -> Fret -> Fret
setTone tone fret =
    { fret | tone = tone }

Если вы планируете выполнять много вложенных обновлений, вы можете рассмотреть возможность использования линз из такой библиотеки, как arturopala/elm-monocle (вот небольшой пример из другого ответа StackOverflow).

person Chad Gilbert    schedule 11.08.2017
comment
не могли бы вы поместить это в ОДНУ функцию? - person Timo; 12.08.2017
comment
Вы точно могли бы. Просто используйте выражение let/in. - person Chad Gilbert; 12.08.2017