如何在集合上减少(),将集合本身保留在 Scala 中?
How to reduce() on a collection keeping the collection itself in Scala?
我只需要减少集合中的元素,但我想在结果中保留集合。
scala> List("a","b","c").reduce(_+_)
res0: String = abc
我想得到
scala> List("a","b","c").someSortOfReduce(_+_)
res0: List[String] = List(abc)
scala> Seq("a","b","c").someSortOfReduce(_+_)
res1: Seq[String] = Seq(abc)
由于你想要的集合和原始集合不共享任何条目,你可以将 reduce 的结果包装在你想要的任何东西中。
Seq(original.reduce(_+_))
我自己找到了解决方案
val list = List("a","b","c")
list.companion(list.reduce(_+_))
使用companion
方法
def red[T](a: Iterable[T], f: (T,T) => T) = a.companion(a.reduce(f))
已编辑
如果您需要保留静态类型,一个选项是使用 asInstanceOf
implicit class Reduce[T, C[T] <: Iterable[T]](s: C[T]) {
def someSortOfReduce(f: (T, T) => T): C[T] = s.companion(s.reduce(f)).asInstanceOf[C[T]]
}
val list = List(1, 2, 3).someSortOfReduce(_ + _) // list: List[Int] = List(6)
val set = Set(1, 2, 3).someSortOfReduce(_ + _) // set: Set[Int] = Set(6)
或模式匹配
implicit class Reduce[T, C[T] <: Iterable[T]](s: C[T]) {
def someSortOfReduce(f: (T, T) => T): C[T] = s.companion(s.reduce(f)) match {
case a: C[T] => a
}
}
这是一种方法(可能不是最优雅的,但是,嘿,它有效):
import collection.generic._
def reduceAsCollection[E,C[_]](s: C[E])(f: (E,E) => E)(implicit cbf: CanBuildFrom[Nothing, E, C[E]], e: C[E] <:< TraversableOnce[E]): C[E] = {
(cbf() += s.reduce(f)).result
}
以及强制性 REPL 测试:
scala> reduceAsCollection(List("a","b","c"))(_+_)
res14: List[String] = List(abc)
scala> reduceAsCollection(Seq("a","b","c"))(_+_)
res15: Seq[String] = Vector(abc)
如您所见,不仅生成的集合具有适当的运行时类型,而且还保留了静态类型(给 Seq
返回 Seq
,给 List
, 获得 List
回报)。
我只需要减少集合中的元素,但我想在结果中保留集合。
scala> List("a","b","c").reduce(_+_)
res0: String = abc
我想得到
scala> List("a","b","c").someSortOfReduce(_+_)
res0: List[String] = List(abc)
scala> Seq("a","b","c").someSortOfReduce(_+_)
res1: Seq[String] = Seq(abc)
由于你想要的集合和原始集合不共享任何条目,你可以将 reduce 的结果包装在你想要的任何东西中。
Seq(original.reduce(_+_))
我自己找到了解决方案
val list = List("a","b","c")
list.companion(list.reduce(_+_))
使用companion
方法
def red[T](a: Iterable[T], f: (T,T) => T) = a.companion(a.reduce(f))
已编辑
如果您需要保留静态类型,一个选项是使用 asInstanceOf
implicit class Reduce[T, C[T] <: Iterable[T]](s: C[T]) {
def someSortOfReduce(f: (T, T) => T): C[T] = s.companion(s.reduce(f)).asInstanceOf[C[T]]
}
val list = List(1, 2, 3).someSortOfReduce(_ + _) // list: List[Int] = List(6)
val set = Set(1, 2, 3).someSortOfReduce(_ + _) // set: Set[Int] = Set(6)
或模式匹配
implicit class Reduce[T, C[T] <: Iterable[T]](s: C[T]) {
def someSortOfReduce(f: (T, T) => T): C[T] = s.companion(s.reduce(f)) match {
case a: C[T] => a
}
}
这是一种方法(可能不是最优雅的,但是,嘿,它有效):
import collection.generic._
def reduceAsCollection[E,C[_]](s: C[E])(f: (E,E) => E)(implicit cbf: CanBuildFrom[Nothing, E, C[E]], e: C[E] <:< TraversableOnce[E]): C[E] = {
(cbf() += s.reduce(f)).result
}
以及强制性 REPL 测试:
scala> reduceAsCollection(List("a","b","c"))(_+_)
res14: List[String] = List(abc)
scala> reduceAsCollection(Seq("a","b","c"))(_+_)
res15: Seq[String] = Vector(abc)
如您所见,不仅生成的集合具有适当的运行时类型,而且还保留了静态类型(给 Seq
返回 Seq
,给 List
, 获得 List
回报)。