I would like to do a function to swap two elements in array.
Obviously if it is triggered Up
msg with first element, nothing will happens. Same if Down
msg with latest element.
I have the following code:
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Attributes exposing (class)
import Html.Events exposing (onClick)
import Array
import List exposing (map)
type alias Model = Array.Array Int
initialModel : Model
initialModel =
Array.fromList [3, 1, 7, 2, 6, 4, 5]
type Msg
= Up Int
| Down Int
update : Msg -> Model -> Model
update msg model =
case msg of
Up n ->
swap model n (n-1)
Down n ->
swap model n (n+1)
swap : Model -> Int -> Int -> Model
swap model src dest =
model -- How do it?
view : Model -> Html Msg
view model =
div [] (map elements (Array.toIndexedList model))
elements : (Int, Int) -> Html Msg
elements (position, number) =
div [ class "block" ]
[ button [ onClick (Up position) ] [ text "UP" ]
, div [] [ text <| String.fromInt number ]
, button [ onClick (Down position) ] [ text "DOWN" ]
]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
And I would like to know if it is better using List or Array to do that.
Thank you very much
I would generally prefer to use a List instead of Array, but if you don't plan to add new items to your list, an Array would likely make more sense.
A pro of Array is that accessing a specific element is faster, but if you only have a few items you probably won't have to worry about performance. Also converting from Array to List is also not without performance costs.
Option 1: If you keep using an Array, you could solve it e.g. like this:
src
and dest
and bail early if one of them returns Nothing
(this will cover the cases where a index is out of bounds)Option 2: If you use a List instead, you could for instance use the elm-community/list-extra package.
It has a swapAt function that does what you need.
Option 3: Can be implemented for either List or Array, but you will need to implement a custom behavior that traverses all the elements and builds a new Array/List, which is out of scope for now I think.
Regards, marc