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

如何使用Arrow Optics构建Lens实现列表元素的过滤与修改?

使用Arrow Optics过滤并修改列表元素的实现方案

当然可以实现你的需求,不过不能直接用你尝试的filter+set方式——因为Lens聚焦的是单个值或可遍历的集合,直接过滤后无法直接绑定到修改元素属性的操作上。下面是两种可行的实现方式:

方式一:修改单个匹配元素(用Optional)

如果确定列表中最多只有一个符合条件的元素(比如code为"1"的Line唯一),可以用Optional定位目标元素,再结合Line.number的Lens完成修改:

"filter and set single matching line"{
    // 构建Optional:定位Order中lines列表里code为"1"的Line
    val targetLineOpt: Optional<Order, Line> = Order.lines
        .find { it.code == "1" }

    // 组合Line.number的Lens,修改目标元素的number为100
    val modifiedOrder = targetLineOpt.compose(Line.number).set(order, 100)

    modifiedOrder shouldBe Order(
        "1",
        listOf(Line("1", 100), Line("2", 2))
    )
}

方式二:修改所有匹配元素(用Traversal)

如果列表中可能有多个符合条件的元素,需要批量修改,就用Traversal遍历所有匹配项:

"filter and modify all matching lines"{
    // 构建Traversal:定位Order中lines列表里所有code为"1"的Line
    val matchingLinesTraversal: Traversal<Order, Line> = Order.lines
        .filter { it.code == "1" }

    // 组合Line.number的Lens,批量修改number为100
    val modifiedOrder = matchingLinesTraversal.compose(Line.number).set(order, 100)

    modifiedOrder shouldBe Order(
        "1",
        listOf(Line("1", 100), Line("2", 2))
    )
}

关键说明

  • Order.lines是自动生成的Lens<Order, List<Line>>,调用find会返回Optional<List<Line>, Line>,和原Lens组合后就能聚焦到Order中符合条件的单个Line。
  • filter方法返回Traversal<List<Line>, Line>,组合后可以遍历所有匹配的Line元素,适合批量修改场景。
  • 两种方式都是通过组合光学组件(Lens + Optional/Traversal)来实现"定位-修改"的链式操作,这也是Arrow Optics的核心设计思想。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:12:21