[英]Map and fold a collection in Scala
I have a fold
which iterates through elements, dependently modifies them one by one and at the same time modifies their parent.我有一个fold
元素,它遍历元素,依赖地一个一个地修改它们,同时修改它们的父级。
Currently I replace the elements in their parent one by one in the fold
, they are just few and it is not a real performance issue, but I wonder if there is perhaps a nicer way to express this.目前我在fold
中一个一个地替换其父元素中的元素,它们很少,这不是真正的性能问题,但我想知道是否有更好的方式来表达这一点。
case class Behavior(x: Int) {
def simulate(s: Entity): Behavior = copy(x = x + (if (s.alternate) 2 else 1))
}
case class Entity(alternate: Boolean, behaviors: List[Behavior]) {
def replaceBehavior(o: Behavior, n: Behavior): Entity = {
copy(behaviors = behaviors.patch(behaviors.indexOf(o), Seq(n), 1))
}
def toggleAlternate: Entity = copy(alternate = !alternate)
def simulate: Entity = {
behaviors.foldLeft(this) { (e, b) =>
e.replaceBehavior(b, b.simulate(e)).toggleAlternate
}
}
}
val entity = Entity(false, List(Behavior(10), Behavior(20), Behavior(30)))
entity.simulate
Is there some operation or perhaps some clever use of scan
or something like that which would allow me to perform foldLeft
and map
dependent of the foldLeft
result in one step?是否有一些操作或一些巧妙地使用scan
或类似的东西可以让我在一步中执行foldLeft
和map
依赖于foldLeft
结果? (I would prefer vanilla standard Scala library, but using functional frameworks is possible too). (我更喜欢香草标准 Scala 库,但也可以使用功能框架)。
Folds ( fold
, foldLeft
, foldRight
, ...) usually turn some Collection[A]
into B
.折叠( fold
, foldLeft
, foldRight
,...)通常将一些Collection[A]
变成B
。
You could map over A
before folding result to B
- foldMap
maps A => B
and assumed existence of Monoid[B]
(this is available in Cats in Foldable
typeclass), so you would perform transformation Collection[A] --using f--> Collection[B] --using Monoid[B]--> B
(code can optimize it to perform things in one step using eg foldLeft
internally).在将结果折叠到B
之前,您可以在A
上 map - foldMap
映射A => B
并假设存在Monoid[B]
(这在Foldable
类型类中的 Cats 中可用),因此您将执行转换Collection[A] --using f--> Collection[B] --using Monoid[B]--> B
(代码可以优化它以在一个步骤中使用例如foldLeft
在内部执行操作)。
Reversing the order of operations - we fold
and then we map
- is in general impossible because there is nothing that can let us assume that after fold
step we will end up with something that is a Functor
.颠倒操作的顺序——我们fold
然后我们map
通常是不可能的,因为没有什么可以让我们假设在fold
步骤之后我们最终会得到一个Functor
的东西。
Depending on your specific use case we might try using foldMap
to achieve your goal.根据您的具体用例,我们可能会尝试使用foldMap
来实现您的目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.