首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Arrow Optics添加/删除不可变列表元素?

如何使用Arrow Optics添加/删除不可变列表元素?
EN

Stack Overflow用户
提问于 2022-11-29 23:00:27
回答 1查看 40关注 0票数 1

我有一个复杂的、不可变的数据结构,其中包括简单的字段,但也包括层次结构中的映射和列表。也许我只是没有足够仔细地阅读文档,但似乎没有一个简单的方法来修改整个列表,而不做一些非常麻烦的事情。

例如,假设我有foo.bar.list,我想在索引i上添加一个元素到列表中。我看到这样做的唯一方法是使用getter获取当前列表,执行以下操作

代码语言:javascript
复制
list.subList(0, i) + listOf(newElement) + list.subList(i, list.size)

把这个交给策划人。

是否有类似于list.add(index, element)list.remove(index)的东西,您可以在镜头内调用它来修改list部件,并保持结构的其余部分不变。

或者,对于集合DSL的AtIndexTraversal部分,有什么简单的方法可以做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2022-11-30 08:15:25

这是可能的与箭光学,和Index,正如你已经指出的。下面是一个完整的例子,

代码语言:javascript
复制
import arrow.optics.dsl.index
import arrow.optics.optics
import arrow.optics.typeclasses.Index

@optics data class Foo(val bar: Bar) {
    companion object
}
@optics data class Bar(val list: List<Int>) {
  companion object
}

val foo = Foo(Bar(listOf(1, 2, 3)))

fun main() {
  Foo.bar.list.index(Index.list(), 1).set(foo, 5)
    .let(::println) // Foo(bar=Bar(list=[1, 5, 3]))
}

当然,你也可以使用光学的其他运算符。这个例子是用Kotlin1.6.21、id("com.google.devtools.ksp") version "1.6.21-1.0.6"和Arrow1.1.3编写的。

当然,如果您不喜欢使用Google,您也可以手工编写光学信息。

代码语言:javascript
复制
import arrow.optics.Lens
import arrow.optics.typeclasses.Index

data class Foo(val bar: Bar)

data class Bar(val list: List<Int>)

val bar: Lens<Foo, Bar> = Lens(Foo::bar) { foo, bar -> foo.copy(bar = bar) }
val list: Lens<Bar, List<Int>> = Lens(Bar::list) { bar, list -> bar.copy(list = list) }

val foo = Foo(Bar(listOf(1, 2, 3)))

fun main() {
  val optic = (bar compose list compose Index.list<Int>().index(1))
  val result = optic.modify(foo) { it + 3 }
  println(result)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74621154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档