Поменяйте местами два элемента в массиве вязов - PullRequest
1 голос
/ 30 апреля 2020

Я хотел бы сделать функцию, чтобы поменять местами два элемента в массиве.

Очевидно, что если он запускается Up msg с первым элементом, ничего не произойдет. То же самое, если Down msg с последним элементом.

У меня есть следующий код:

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
        }

И я хотел бы знать, лучше ли использовать List или Array, чтобы сделать что.

Большое спасибо

1 Ответ

3 голосов
/ 30 апреля 2020

Я бы предпочел использовать Список вместо Массива, но если вы не планируете добавлять новые элементы в свой список, Массив, скорее всего, будет иметь больше смысла.

Преимуществом Массива является то, что доступ к указанному элементу c быстрее, но если у вас всего несколько элементов, вам, вероятно, не придется беспокоиться о производительности. Преобразование из массива в список также не обходится без затрат на производительность.

Вариант 1. Если вы продолжаете использовать массив , вы можете решить его, например, так:

  1. Получите значения в src и dest и получите ранний залог, если один из них вернет Nothing (это будет охватывать случаи, когда индекс выходит за пределы)
  2. Установите значение из sr c в dest и наоборот
  3. Верните новый массив

Опция 2: Если вы используете Вместо списка вы можете, например, использовать пакет elm-community / list-extra .
Он имеет функцию swapAt , которая делает то, что вам нужно.

Вариант 3: Может быть реализован для List или Array , но вам нужно будет реализовать собственное поведение, которое перебирает все элементы и создает новый Array / List, который пока выходит за рамки Я думаю.

С уважением, март c

...