遍历记录字段
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 包含完整定义。
在 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 包含完整定义。