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) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |