你能在榆树中使用字符串进行记录访问吗?

Can you use a string for record access in elm?

如果我有一个看起来像记录中字段名称的字符串,我可以使用它以某种方式获取数据吗?像 :

."name".toKey bill 
bill.(asSymbol "name")

-

song =
  { title = "foot", artist = "barf", number = "13" }

fieldsILike : List String
fieldsILike =
  [ "title", "artist" ]


val song key =
  .key song

foo = List.map (val song) fieldsILike --> should be ["foot", "barf"]

不,但您可以使用 Dict

import Dict exposing (get ,fromList)

song = fromList [ ("title", "foot"), ("artist", "barf") ]

get "title" song -- Just "foot"
get "artist" song -- Just "barf"
get "test" song  -- Nothing

不是您想要的方式,但您可以使用一个函数来匹配字符串的模式以访问记录的一部分。如果你给它一些无效的东西,你需要明确它应该做什么。

import Html exposing (..) 

type alias Song = { artist : String, number : String, title : String }

song : Song
song =
  { title = "foot", artist = "barf", number = "13" }

fieldsILike : List String
fieldsILike =
  [ "title", "artist" ]


k2acc : String -> (Song -> String)
k2acc key = 
  case key of 
  "title" ->  .title
  "artist" -> .artist
  "number" -> .number
  _ ->  always ""

val : Song -> String -> String
val = flip k2acc 
-- `flip` was removed in elm 0.19, so you'll need to 
-- do something like the following going forward: 
-- val song field = (k2acc field) song   

foo = List.map (val song) fieldsILike

main = text <| toString foo

我通过在 AttrValue 类型中添加属性名称和显式类型声明解决了这个问题:

type alias TypedRecord =
    List Attr

type alias Attr =
    ( String, AttrValue )


type AttrValue
    = String String
    | Int Int
    | Record (List Attr)

所以现在我可以通过 "key"(甚至 "key.key" 嵌套)从我的 TypedRecord 类型中检索属性:

getAttrByKey : String -> TypedRecord -> Maybe Attr
getAttrByKey searchKey item =
    -- imitation of searching for attributes likewise in JS Record
    let
        checkAttrKey =
            \k attr ->
                first attr == k
    in
    case String.split "." searchKey of
        [ key ] ->
            List.head <| List.filter (checkAttrKey key) item

        key :: rest ->
            case List.head <| List.filter (checkAttrKey key) item of
                Just attr ->
                    case attr of
                        ( _, Record subAttr ) ->
                            getAttrByKey (String.join "." rest) subAttr

                        ( _, _ ) ->
                            Nothing

                Nothing ->
                    Nothing

        [] ->
            Nothing

并通过检查 Attr 类型并调用尊敬的 Elm String 模块函数将其转换为 String

attrToString : Maybe Attr -> String
attrToString is_attr =
    case is_attr of
        Nothing ->
            ""

        Just attr ->
            case second attr of
                String value ->
                    value

                Int value ->
                    String.fromInt value

                Record attrs ->
                    List.map (\a -> Just a) attrs
                        |> List.map (\a -> attrToString a)
                        |> String.join " "

这些示例适用于 String IntRecord Elm 类型,但它也可以扩展到 Float BoolArray. 您可以检查 src/lib/TypedRecord.elm 文件中的其他功能,甚至可以检查 example app repository

中的 Json 解码器