gpt4 book ai didi

scala - 如何使用 scala 2.13 转换元组集合

转载 作者:行者123 更新时间:2023-12-05 03:44:13 25 4
gpt4 key购买 nike

我想将以下代码从 Scala 2.12 迁移到 2.13

给定任何元组集合 Coll[(A, B)] 和一个方法 f: B => IterableOnce[C],我想生成一个Coll[(A, C)] 通过在元组的第二个元素上应用 f

implicit class TuplesOps[A, B, Repr <: Traversable[(A, B)]](val s: TraversableLike[(A, B), Repr]) extends AnyVal {
def flatMapValues[C, That](f: B => TraversableOnce[C])(implicit bf: CanBuildFrom[Repr, (A, C), That]) =
s.flatMap { case (a, b) => f(b).map((a, _))}
}

我知道收集 API 在 2.13 中发生了变化,我读到:https://docs.scala-lang.org/overviews/core/custom-collection-operations.html

我试过两种实现方式

首先

import scala.collection.{ AbstractView, BuildFrom }
import scala.collection.generic.IsSeq

object Evidence extends App {
class TuplesOps[Repr, S <: IsSeq[Repr]](coll: Repr, seq: S) {
def flatMapValues[B, C, D, That](f: C => IterableOnce[D])(implicit bf: BuildFrom[Repr, (B, D), That], ev: seq.A =:= (B, C)): That = {
val seqOps = seq(coll)
bf.fromSpecific(coll)(new AbstractView[(B, D)] {
override def iterator: Iterator[(B, D)] = {
seqOps.flatMap { x => f(ev(x)._2).map((ev(x)._1, _))}.iterator
}
})
}
}

implicit def TuplesOps[Repr](coll: Repr)(implicit seq: IsSeq[Repr]): TuplesOps[Repr, seq.type] =
new TuplesOps(coll, seq)

List("a"->1, "b"->2).flatMapValues{(x:Int) => Seq.fill(x)("x")}
}

我有这个编译错误:

[error] /home/yamo/projects/perso/coll213/src/main/scala/example/Evidence.scala:22:37: diverging implicit expansion for type scala.collection.BuildFrom[List[(String, Int)],(B, String),That]
[error] starting with method Tuple9 in object Ordering
[error] List("a"->1, "b"->2).flatMapValues{(x:Int) => Seq.fill(x)("x")}

第二

import scala.collection.{ AbstractView, BuildFrom }
import scala.collection.generic.IsSeq

object Aux extends App {
type Aux[Repr, B, C] = IsSeq[Repr] { type A = (B, C)}

class TuplesOps[Repr, B, C, S <: Aux[Repr, B, C]](coll: Repr, seq: S) {
def flatMapValues[D, That](f: C => IterableOnce[D])(implicit bf: BuildFrom[Repr, (B, D), That]): That = {
val seqOps = seq(coll)
bf.fromSpecific(coll)(new AbstractView[(B, D)] {
// same as before
override def iterator: Iterator[(B, D)] = {
seqOps.flatMap { case (b, c) => f(c).map((b, _))}.iterator
}
})
}
}

implicit def TuplesOps[Repr, B, C](coll: Repr)(implicit seq: Aux[Repr, B, C]): TuplesOps[Repr, B, C, seq.type] =
new TuplesOps(coll, seq)

List("a"->1, "b"->2).flatMapValues(Seq.fill(_)("x"))
}

我有这个编译错误

[error] /home/yamo/projects/perso/coll213/src/main/scala/example/Aux.scala:24:24: value flatMapValues is not a member of List[(String, Int)]
[error] List("a"->1, "b"->2).flatMapValues(Seq.fill(_)("x"))

如果可能的话,你能帮我解决这两个问题吗?

最佳答案

我同意,Custom Collection instructions不是他们应该的样子。

我发现 Factory 方法比 BuildFrom 方法简单一些,但我仍然习惯了其中一个/两个方法。

import scala.collection.Factory

implicit
class TuplesOps[A,B,CC[x] <: Iterable[x]](val ts: CC[(A,B)]) {
def flatMapValues[C](f: B => IterableOnce[C]
)(implicit fac: Factory[(A,C), CC[(A,C)]]
): CC[(A,C)] =
ts.flatMap{case (a,b) => f(b).iterator.map(x => (a,x))}
.to[CC[(A,C)]](fac)
}

这通过了我所有的简单(头脑)测试。它不能在 ArrayIterator 上运行,但是你原来的 Scala 2.12.x 版本也没有(对我来说),所以我认为没问题。

关于scala - 如何使用 scala 2.13 转换元组集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66591072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com