首页 > 解决方案 > 如何按 Scala 中元素列表的各个元素进行分组

问题描述

如果我没有用它们的实际名称命名事物,请原谅我,我刚刚开始学习 Scala。我已经环顾四周,但找不到我的问题的明确答案。

假设我有一个对象列表,每个对象都有两个字段:x: Intl: List[String],在我的例子中,字符串代表类别。

列表可以是任意长度,因此l一个对象可以属于多个类别。此外,各种对象可以属于同一类别。我的目标是按各个类别对对象进行分组,其中类别是键。这意味着如果一个对象链接到“N”个类别,它将出现在“N”个键值对中。

到目前为止,我设法通过以下方式对类别列表进行分组: objectList.groupBy(x => x.l) 但是,这显然是按类别列表而不是按类别对对象进行分组。

我正在尝试通过避免循环等的不可变集合来做到这一点。

如果有人有一些想法,将不胜感激!谢谢

编辑:通过请求实际案例类和我正在尝试的内容。 case class Car(make: String, model: String, fuelCapacity: Option[Int], category:Option[List[String]]) 再一次,汽车可以属于多个类别。比方说List("SUV", "offroad", "family")

我想按category元素而不是整个类别列表进行分组,并将其fuelCapacity作为值,以便能够fuelCapacity在其他指标中提取每个类别的平均值。

标签: scala

解决方案


像下面这样的东西?

objectList // Seq[YourType]
  .flatMap(o => o.l.map(c => c -> o)) // Seq[(String, YourType)]
  .groupBy { case (c,_) => c } // Map[String,Seq[(String,YourType)]]
  .mapValues { items => c -> items.map { case (_, o) => o } } // Map[String, Seq[YourType]]

(特意“重磅”来帮你理解背后的思路)

编辑,或从 Scala 2.13 开始,感谢groupMap

objectList // Seq[YourType]
  .flatMap(o => o.l.map(c => c -> o)) // Seq[(String, YourType)]
  .groupMap { case (c,_) => c } { case (_, o) => o } // Map[String,Seq[YourType]]

推荐阅读