按值减少scala中的列表
我怎样才能简明扼要地减少下面这样的列表按值减少scala中的列表,scala,reduce,Scala,Reduce,我怎样才能简明扼要地减少下面这样的列表 Seq[Temp] = List(Temp(a,1), Temp(a,2), Temp(b,1)) 到 仅保留具有唯一第一个参数和第二个参数最大值的临时对象 我的解决方案是使用大量的groupby和reduces,这会给出一个冗长的答案。您必须 groupBy 按ASC顺序排序 获取最后一个最大的 例如 scala> final case class Temp (a: String, value: Int) defined class Temp
Seq[Temp] = List(Temp(a,1), Temp(a,2), Temp(b,1))
到
仅保留具有唯一第一个参数和第二个参数最大值的临时对象
我的解决方案是使用大量的groupby和reduces,这会给出一个冗长的答案。您必须
groupBy
按ASC顺序排序
- 获取最后一个最大的
scala> final case class Temp (a: String, value: Int)
defined class Temp
scala> val data : Seq[Temp] = List(Temp("a",1), Temp("a",2), Temp("b",1))
data: Seq[Temp] = List(Temp(a,1), Temp(a,2), Temp(b,1))
scala> data.groupBy(_.a).map { case (k, group) => group.sortBy(_.value).last }
res0: scala.collection.immutable.Iterable[Temp] = List(Temp(b,1), Temp(a,2))
或者代替sortBy(fn)。最后
您可以maxBy(fn)
您可以使用
groupBy
生成Map
,在mapValues
中计算max
,并将其转换回Temp
类,如下例所示:
case class Temp(id: String, value: Int)
List(Temp("a", 1), Temp("a", 2), Temp("b", 1)).
groupBy(_.id).mapValues( _.map(_.value).max ).
map{ case (k, v) => Temp(k, v) }
// res1: scala.collection.immutable.Iterable[Temp] = List(Temp(b,1), Temp(a,2))
值得注意的是,在另一个答案中使用
maxBy
的解决方案效率更高,因为它最大限度地减少了必要的转换。您可以使用foldLeft
:
data.foldLeft(Map[String, Int]().withDefaultValue(0))((map, tmp) => {
map.updated(tmp.id, max(map(tmp.id), tmp.value))
}).map{case (i,v) => Temp(i, v)}
这实质上是将groupBy
的逻辑与max
操作结合在一起
注意这可能效率较低,因为groupBy
在内部使用mutable.Map
,从而避免不断重新创建新的映射。如果您关心性能并准备使用可变数据,这是另一种选择:
val tmpMap = mutable.Map[String, Int]().withDefaultValue(0)
data.foreach(tmp => tmpMap(tmp.id) = max(tmp.value, tmpMap(tmp.id)))
tmpMap.map{case (i,v) => Temp(i, v)}.toList
如果需要保留数据顺序,请使用ListMap
,如果需要特定顺序,请在末尾排序。您可以更改排序方式(.value)。最后更改为maxBy(.value)
data.foldLeft(Map[String, Int]().withDefaultValue(0))((map, tmp) => {
map.updated(tmp.id, max(map(tmp.id), tmp.value))
}).map{case (i,v) => Temp(i, v)}
val tmpMap = mutable.Map[String, Int]().withDefaultValue(0)
data.foreach(tmp => tmpMap(tmp.id) = max(tmp.value, tmpMap(tmp.id)))
tmpMap.map{case (i,v) => Temp(i, v)}.toList