遍历记录字段

Iterating through record fields

在 Elm 中,我的一条记录(type alias 构造)有很多条目,我想知道是否有内置的方法来遍历它。直接或将其转换为 Dict

所以我在想:

let
  myRecord = MyRecord ...
  showEntry key value = ...
in
  map showEntry myRecord

感谢您的宝贵时间!

更新

为了回答有关实际数据的问题,我有12个相同类型的字段。 12 个字段都需要具有准确的名称,因此是记录类型,而不是 Dict。无论它是在记录中命名为字符串还是在其本身中命名都无关紧要,只要我可以从其他 11 中唯一地识别该值。在代码中,记录看起来像:

type alias InnerType { value : Int, ... }

type alias Record = { inner1 : InnerType, inner2 : InnerType, ... }

由于记录中的所有字段都具有相同的类型,我只是想看看是否有更简单的方法来遍历它们而不是命名所有 12 个。除非有更好的方法来表示它,在这种情况下我洗耳恭听! :-)

看起来您需要一个 List(或 Array)的 InnerType,正如您所说,结构本身固定为其中的 12 个。至于迭代,这里是 json 编码 InnerType

列表的示例
inners 
  |> List.indexedMap (\idx inner -> ("inner" ++ toString idx, encodeInner inner))
  |> Json.Encode.object 

如果您的记录 只有 有十二个元素,并且您不介意为了类型安全而在类​​型定义中牺牲一点冗长 (make impossible states impossible!),您可以从枚举那十二个指标开始:

type Index
    = Inner1
    | Inner2
    ...
    | Inner12

您可以将 Record 重新定义为 type 而不是记录类型别名:

type Record =
    Record
        InnerType
        InnerType
        -- repeat InnerType 12 times

现在您可以创建一些方便的函数来以类型安全的方式获取和设置值:

get : Index -> Record -> InnerType
get i (Record i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12) =
    case i of
        Inner1 -> i1
        Inner2 -> i2
        ...
        Inner12 -> i12

set : Index -> InnerType -> Record -> Record
set i val (Record i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12) =
    case i of
        Inner1 -> Record val i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
        Inner2 -> Record i1 val i3 i4 i5 i6 i7 i8 i9 i10 i11 i12
        ...
        Inner12 -> Record i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 val

您可以像这样从您的记录中创建一个列表:

toList : Record -> List InnerType
toList (Record i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12) =
    [ i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12 ]

如您所见,这变得冗长,但只有在 Record 类型的定义中才会变得冗长。如果将所有这些代码限制在一个 Record 模块中,那么访问和修改记录是干净、简洁的,更重要的是,类型安全。您不受可能不存在键的字典或可能不存在索引的列表或数组的约束。您的 Record 类型将被很好地密封起来,代价是定义有点冗长。

Here is a gist 包含完整定义。