You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Elm中为列表中的Record元素按类型分别分配pos编号

实现思路

Elm 是纯函数式语言,不存在可变变量,这类需要累计计数的场景可以用 List.foldl 来实现,通过遍历过程中维护计数状态的方式完成编号,全程不会修改原列表,符合 Elm 的不可变特性。


完整实现代码

首先先补充你没给出的 B 类型定义(按照要求和 A 一样带 pos 字段):

type alias B =
  { pos : Maybe Int
  , type : Char
  }

对应的核心逻辑代码如下:

-- 遍历单个元素时的状态更新逻辑
updateRecord : Record -> (Int, Int, List Record) -> (Int, Int, List Record)
updateRecord record (countA, countB, processedList) =
  case record of
    RecordA a ->
      let
        newCountA = countA + 1
        updatedA = { a | pos = Just newCountA }
      in
      (newCountA, countB, RecordA updatedA :: processedList)
    
    RecordB b ->
      let
        newCountB = countB + 1
        updatedB = { b | pos = Just newCountB }
      in
      (countA, newCountB, RecordB updatedB :: processedList)

-- 对外暴露的处理函数
assignPos : List Record -> List Record
assignPos originalList =
  List.foldl updateRecord (0, 0, []) originalList
    |> (\(_, _, result) -> List.reverse result)

用法示例

直接把你要处理的原始列表传入 assignPos 函数即可得到编号后的新列表:

-- 示例输入
sampleList : List Record
sampleList =
  [ RecordA { pos = Nothing, type = 'A' }
  , RecordB { pos = Nothing, type = 'B' }
  , RecordA { pos = Nothing, type = 'A' }
  ]

-- 处理后得到的结果为
-- [ RecordA { pos = Just 1, type = 'A' }
-- , RecordB { pos = Just 1, type = 'B' }
-- , RecordA { pos = Just 2, type = 'A' }
-- ]
processedList : List Record
processedList = assignPos sampleList

说明

  1. List.foldl 遍历过程中维护的三元组分别是当前 A 类型的计数、B 类型的计数、已经处理完成的记录列表
  2. 因为每次把新处理的元素加到列表头部,最后要调用 List.reverse 反转列表,保证和原列表的顺序一致
  3. 所有操作都是生成新的对象,不会修改原始输入的列表和元素

内容的提问来源于stack exchange,提问作者az5112

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:54:02