在不知道所有项目的情况下删除记录项目

Remove item of record without knowing all item

我有这个模拟:

 init : (Model, Cmd Msg)
    init = ({ dog = List Dog }, Cmd.none)

    type alias Dog =
      { name : String
      , age : Int
      , price : Float
      , extra = List Extra
      }

    type alias Extra =
      { allergies : List String
      , wishes : List String
      }


    [{ name = "Hot"
     , age = 1
     , price = 300.5
     , extra = [{...}]
     },
     { name = "Dog"
     , age = 3
     , price = 150.0
     , extra = [{...}]
    }]

我只想删除 'extras' 的 Dog,在代码的确定部分:

[{ name = "Hot"
 , age = 1
 , price = 300.5
 },
 { name = "Dog"
 , age = 3
 , price = 150.0
}]

我可以通过映射整个列表并通过删除 'extra' 项生成一个新列表来做到这一点:

removeExtraOfDogs dogList =  
     (dogList |> List.map (\dog ->
          { name = dog.name
          , age = dog.age
          , price = dog.price
          }
        )) 

但我想让它动态化,只传递要删除的额外内容,而不必知道类型中有哪些变量并重新创建它

Elm 曾经有此功能,但 it was removed a while ago。但是,根据您在评论中描述的用例,我认为您不需要此功能。您可以改用 Elm 的可扩展记录功能,允许将不同的记录传递给一个函数,只要它们包含一组固定的字段即可。

例如,假设您有两个类型,其中包含 nameage 字段,并且有一个额外的不兼容字段:

type alias Foo = { name : String, age : Int, extra : List String }
type alias Bar = { name : String, age : Int, extra : Int }

您可以定义一个函数,该函数使用 String 类型的 name 字段和 Int 类型的 age 字段以及任何额外字段:

encode : { r | name : String, age : Int } -> String
encode record = record.name ++ "," ++ toString record.age

您现在可以将 FooBar 都传递给此函数,因为它们都满足类型签名的要求。