groupBy
的类型签名是(用scala语言,但实际上与语言无关):
def groupBy[K](f: A => K): Map[K, Seq[A]]
我实施了groupBy
,返回多个K
,以便每个A
可以同时放入多个组。像这样:
def multiGroupBy[K](f: A => Seq[K]): Map[K, Seq[A]]
我做的事情如下:
case class Animal(name: String, traits: Seq[String])
List(
Animal("cat", Seq("nocturnal", "feline")),
Animal("dog", Seq("canine")),
Animal("wolf", Seq("nocturnal", "canine"))
).multiGroupBy(animal => animal.traits)
// Map(nocturnal -> List(cat, wolf), feline -> List(cat), canine -> List(dog, wolf))
名称multiGroupBy
有效,但我想知道是否已有一个术语(可能在haskell世界中?),如上所述。
答案 0 :(得分:1)
如果您有Scalaz
依赖关系,则可以使用foldMap
执行此操作。
import scalaz._
import Scalaz._
case class Animal(name: String, traits: Seq[String])
val animals = List(
Animal("cat", Seq("nocturnal", "feline")),
Animal("dog", Seq("canine")),
Animal("wolf", Seq("nocturnal", "canine"))
)
val r1 = animals.foldMap(a => a.traits.map(t => t -> List(a)).toMap)
println(r1)
// Map(nocturnal -> List(Animal(cat,List(nocturnal, feline)), Animal(wolf,List(nocturnal, canine))), feline -> List(Animal(cat,List(nocturnal, feline))), canine -> List(Animal(dog,List(canine)), Animal(wolf,List(nocturnal, canine))))
val r2 = animals.foldMap(a => a.traits.map(t => t -> List(a.name)).toMap)
println(r2)
// Map(nocturnal -> List(cat, wolf), feline -> List(cat), canine -> List(dog, wolf))
我们在这里做的是我们为动物列表中的每只动物创建了一个Map[String, List[Animal]]
,让Monoid[Map[String, List[Animal]]]
合并每个地图。
例如Animal("cat", Seq("nocturnal", "feline"))
变为Map("nocturnal" -> List(Animal("cat", Seq("nocturnal", "feline"))), "feline" -> List(Animal("cat", Seq("nocturnal", "feline"))))
。