[英]How can I group by the individual elements of a list of elements in Scala
如果我没有用他们的实际名称命名,请原谅我,我刚刚开始学习 Scala。我已经四处寻找了一段时间,但找不到我的问题的明确答案。
假设我有一个对象列表,每个 object 都有两个字段: x: Int
和l: List[String]
,在我的例子中,字符串代表类别。
l
个列表可以是任意长度,因此一个 object 可以属于多个类别。 此外,各种对象可以属于同一类别。 我的目标是按各个类别对对象进行分组,其中类别是键。 这意味着如果 object 被链接到说“N”个类别,它将出现在“N”个键值对中。
到目前为止,我设法通过以下方式对类别列表进行分组: objectList.groupBy(x => xl)
但是,这显然是按类别列表而不是按类别对对象进行分组。
我正在尝试使用不可变的 collections 来避免循环等。
如果有人有一些想法,将不胜感激! 谢谢
编辑:通过请求实际案例 class 和我正在尝试的。 case class Car(make: String, model: String, fuelCapacity: Option[Int], category:Option[List[String]])
同样,一辆汽车可以属于多个类别。 比方说List("SUV", "offroad", "family")
。
我想按category
元素而不是整个类别列表进行分组,并将fuelCapacity
作为值,以便能够在其他指标中提取每个类别的平均fuelCapacity
。
像下面这样的东西?
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]]
使用您的编辑作为指南。
case class Car( make: String
, model: String
, fuelCapacity: Option[Int]
, category:Option[List[String]] )
val cars: List[Car] = ???
//all currently known category strings
val cats: Set[String] = cars.flatMap(_.category).flatten.toSet
//category -> list of cars in this category
val catMap: Map[String,List[Car]] =
cats.map(cat => (cat, cars.filter(_.category.contains(cat)))).toMap
//category -> average fuel capacity for cars in this category
val fcAvg: Map[String,Double] =
catMap.map{case (cat, cars) =>
val fcaps: List[Int] = cars.flatMap(_.fuelCapacity)
if (fcaps.lengthIs < 1) (cat, -1d)
else (cat, fcaps.sum.toDouble / fcaps.length)
}
你非常接近,你只需要在group
之前拆分列表中的每个单独元素,所以尝试这样的事情:
// I used a Set instead of a List,
// since I don't think the order of categories matters
// as well I would think having two times the same category doesn't make sense.
final case class MyObject(x: Int, categories: Set[String] = Set.empty) {
def addCategory(category: String): MyObject =
this.copy(categories = this.categories + category)
}
def groupByCategories(data: List[MyObject]): Map[String, List[Int]] =
data
.flatMap(o => o.categories.map(c => c -> o.x))
.groupMap(_._1)(_._2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.