按值减少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