对浮点数,整数或字符串进行排序

时间:2016-10-05 14:54:40

标签: elm

我正在尝试创建一个可排序的表来获取不同类型的数据。在将其渲染为网格之前,我将所有数据转换为字符串(用于视图)。但是,elm无法正确排序浮点数或整数转换为字符串的列表(最终会得到类似1,1001,10.03,21,3.4 ......的内容)。 我有创建联合类型的想法,

type ColType
    = StrCol String
    | IntCol String
    | FloatCol String
    | BoolCol String

但是,在某些时候我需要转换回String,如果它是StrCol,或者Int转换为IntCol等,然后排序;但我不知道该怎么做。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可以创建一个将每个标记的内容转换为字符串的函数:

colTypeToString : ColType -> String
colTypeToString colType =
    case colType of
        StrCol x -> toString x
        IntCol x -> toString x
        FloatCol x -> toString x
        BoolCol x -> toString x

答案 1 :(得分:0)

以下是您可以尝试的示例。

我使用Dict来表示数据记录 Value可以是FloatString 定义ColType(你的建议)。 (很容易扩展以支持其他comparable类型。)

-- MODEL
type alias Model =
  { rows : List Row
  , cols : List String
  , sortkey : Maybe String
  }

type alias Row = Dict.Dict String Value
createRow : String -> Float -> Row
createRow name val = Dict.fromList
  [ ("name", StrValue name)
  , ("value", FloatValue val)
  ]

type Value
  = StrValue String
  | FloatValue Float

init : (Model, Cmd Msg)
init =
  let
    rows =
      [ createRow "A" 1.5
      , createRow "B" 0.5
      ]
    cols = ["name", "value"]
    sortkey = Nothing
  in (Model rows cols sortkey, Cmd.none)

-- VIEW
view : Model -> Html Msg
view model =
  let
    renderRow cols row = tr [] <| List.map (renderValue row) cols
    renderValue row key = case (Dict.get key row) of
      Just (StrValue str) -> td [] [text str]
      Just (FloatValue num) -> td [] [text <| toString num]
      _ -> td [] [text "-"]
    renderHeaders cols = tr []
      <| List.map renderHeaderName model.cols
    renderHeaderName colname =
      th [ onClick (Sort colname) ]
        <| if Just colname == model.sortkey
           then [ text <| colname ++ "*" ]
           else [ text colname ]
  in
    table []
      <| [ renderHeaders model.cols ]
      ++ List.map (renderRow model.cols) model.rows

-- UPDATE
type Msg
  = Sort String

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Sort name ->
      let
        sortedRows = List.sortWith compareVal model.rows
        compareVal a b = case (Dict.get name a, Dict.get name b) of
          (Just (StrValue sa), Just (StrValue sb)) -> compare sa sb
          (Just (FloatValue na), Just (FloatValue nb)) -> compare na nb
          _ -> EQ
      in ({ model | rows = sortedRows, sortkey = Just name }, Cmd.none)