加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 清除元组groupBy

发布时间:2020-12-16 09:44:31 所属栏目:安全 来源:网络整理
导读:我有一个键值对序列(String,Int),我想通过键将它们分组成一个值序列(即Seq [(String,Int)])= Map [String,Iterable [Int]]))。 显然,toMap在这里是没有用的,groupBy将值保持为元组。我设法想出的最好的是: val seq: Seq[( String,Int )]// ...seq.gro
我有一个键值对序列(String,Int),我想通过键将它们分组成一个值序列(即Seq [(String,Int)])=> Map [String,Iterable [Int]]))。

显然,toMap在这里是没有用的,groupBy将值保持为元组。我设法想出的最好的是:

val seq: Seq[( String,Int )]
// ...
seq.groupBy( _._1 ).mapValues( _.map( _._2 ) )

有没有更干净的方法呢?

解决方法

这是一个添加toMultiMap方法到可移植的皮条客。会解决你的问题吗?

import collection._
import mutable.Builder
import generic.CanBuildFrom

class TraversableOnceExt[CC,A](coll: CC,asTraversable: CC => TraversableOnce[A]) {

  def toMultiMap[T,U,That](implicit ev: A <:< (T,U),cbf: CanBuildFrom[CC,That]): immutable.Map[T,That] =
    toMultiMapBy(ev)

  def toMultiMapBy[T,That](f: A => (T,U))(implicit cbf: CanBuildFrom[CC,That] = {
    val mutMap = mutable.Map.empty[T,mutable.Builder[U,That]]
    for (x <- asTraversable(coll)) {
      val (key,value) = f(x)
      val builder = mutMap.getOrElseUpdate(key,cbf(coll))
      builder += value
    }
    val mapBuilder = immutable.Map.newBuilder[T,That]
    for ((k,v) <- mutMap)
      mapBuilder += ((k,v.result))
    mapBuilder.result
  }
}

implicit def commomExtendTraversable[A,C[A] <: TraversableOnce[A]](coll: C[A]): TraversableOnceExt[C[A],A] =
  new TraversableOnceExt[C[A],A](coll,identity)

可以这样使用:

val map = List(1 -> 'a',1 -> 'à',2 -> 'b').toMultiMap
println(map)  // Map(1 -> List(a,à),2 -> List(b))

val byFirstLetter = Set("abc","aeiou","cdef").toMultiMapBy(elem => (elem.head,elem))
println(byFirstLetter) // Map(c -> Set(cdef),a -> Set(abc,aeiou))

如果添加以下隐含的defs,它也可以使用类似集合的对象,如字符串和数组:

implicit def commomExtendStringTraversable(string: String): TraversableOnceExt[String,Char] =
  new TraversableOnceExt[String,Char](string,implicitly)

implicit def commomExtendArrayTraversable[A](array: Array[A]): TraversableOnceExt[Array[A],A] =
  new TraversableOnceExt[Array[A],A](array,implicitly)

然后:

val withArrays = Array(1 -> 'a',2 -> 'b').toMultiMap
println(withArrays) // Map(1 -> [C@377653ae,2 -> [C@396fe0f4)

val byLowercaseCode = "Mama".toMultiMapBy(c => (c.toLower.toInt,c))
println(byLowercaseCode) // Map(97 -> aa,109 -> Mm)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读