Elm - update elements in a list

Deadly 提交于 2019-12-05 08:53:06

Now that you've clarified your question, the real answer is a combination of the two updates Chad posted

updateElement : List (ID, Task) -> Int -> List (ID, Task)
updateElement list indexToFocusOn =
  let
    toggle index (id, task) =
      if index == indexToFocusOn then
        (id, { task | focus = true })
      else
        (id, { task | focus = false })
  in
    List.indexedMap toggle list

Since you want to update all elements in the list (to make sure all elements are either False while those matching the ID are True), you can perform a List.map over the list, while supplying a function whose job is to check the index and perform the update on the element.

Here's an example with a few minor changes to your example code:

type alias MyTask =
  { description : String
  , focus : Bool
  }

updateElement : List (a, MyTask) -> a -> List (a, MyTask)
updateElement list id =
  let
    toggle (idx, task) =
      if id == idx then
        (idx, { task | focus = True })
      else
        (idx, { task | focus = False })
  in
    List.map toggle list

I changed your signatures to be more generic. Since you provided no indication of what ID was, I assumed that the first element in the tuple had to match the type of whatever the second function parameter was. I also replaced Task with MyTask since there's already a common type in elm called Task.

I'll also mention that there is a List.indexedMap function which could let you simplify your function declaration a little bit. If the only reason you have a tuple input and output in your example above is because you need to locate an element by its index, it's probably easier to use List.indexedMap. Here's an example:

updateElement2 : List MyTask -> Int -> List MyTask
updateElement2 list id =
  let
    toggle idx task =
      if id == idx then
        { task | focus = True }
      else
        { task | focus = False }
  in
    List.indexedMap toggle list

As you can see, it cuts some of that tuple boilerplate out of the function, making it a bit cleaner.

If you want often to change only the nth element of a list, a List would be the wrong data structure. A List in elm is implemented as a linked list, which will not fare well in terms of performance with random access.

For that kind of work, you probably should rather use an elm Array, and indeed the Array does have a simple function to set the nth element, leaving all the others untouched: Array.set :: Int -> a -> Array a -> Array a.

On that topic, this discussion on the elm bug tracker could be of interest.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!