如何从Scala中的列表中获取任意属性的最大值?

rye*_*guy 5 scala

假设我有一个看起来像这样的类:

class Foo(Prop1:Int, Prop2:Int, Prop3:Int)
{
 ..
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个函数,从Foos 列表中获取一些任意属性的最大值.

像这样:

def getMax(Foos:List[Foo], Property:??) = Foos.map(_.Property).sort(_ > _).head
Run Code Online (Sandbox Code Playgroud)

如果我打电话getMax(myFooList, Prop1),它将Prop1从此Foos 列表中返回最高值.

我的问题是,我怎样才能做到这一点?我想我可以创建某种枚举(scala等价物)Property并执行a match然后运行map相应的属性,但这似乎很多工作 - 我必须每次扩展我的枚举和函数Foo被重构.

此外,不是那么重要,但有没有更好的方法来获取列表的最大值然后我做了什么?

Ala*_*son 12

您可以这样做,只需使用现有功能,编写自己的getMax可能是不必要的:

scala> val fooList = List(Foo(1,2),Foo(2,2),Foo(3,2),Foo(4,2))
fooList: List[Foo] = List(Foo(1,2), Foo(2,2), Foo(3,2), Foo(4,2))

scala> fooList.map(_.p2).max
res12: Int = 2

scala> fooList.map(_.p1).max
res13: Int = 4
Run Code Online (Sandbox Code Playgroud)

如果你想在其他地方指定属性'getter',你可以这样做:

scala> def p1 = (f: Foo) => f.p1
p1: Foo => Int

scala> def p2 = (f: Foo) => f.p2
p2: Foo => Int

scala> fooList.map(p1).max
res14: Int = 4

scala> fooList.map(p2).max
res15: Int = 2
Run Code Online (Sandbox Code Playgroud)


Vas*_*tin 11

你应该使用标准maxBy方法:

List(("a", 2), ("b", 3), ("c", 4)).maxBy(_._2)
=> (String, Int) = (c,4)
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以简单地将另一个函数传递给getMax,以指示它如何映射每个Foo:

case class Foo(p1:Int, p2:Int)

def getMax(foos:List[Foo], mapper:Foo=>Int):Int = foos.map(mapper).foldLeft(Math.MIN_INT)((i,m)=>m.max(i))

val fooList = List(Foo(1,2),Foo(2,2),Foo(3,2),Foo(4,2))

getMax(fooList,_.p1)
//-->  4
Run Code Online (Sandbox Code Playgroud)

  • `reduceLeft`方法不适用于空列表,因此应谨慎使用. (2认同)