简体   繁体   English

在Scala中使用foreach查找最大值

[英]Find maximum using foreach in Scala

I have some collection, that implements def foreach(f: MyType => Unit): Unit . 我有一些实现def foreach(f: MyType => Unit): Unit集合。

MyType has member val value: Int that is greater or equals to zero in normal case. MyType具有成员val value: Int在正常情况下, val value: Int大于或等于零。

How coud i find element with maximum value using foreach ? 我coud如何找到最大元素value使用foreach

UPD: UPD:

There should be method def max: MyType within MyType implementing this logic. MyType应该有方法def max: MyType MyType实现此逻辑。

Traversable 可穿越

You could implement scala.collection.Traversable - then you could use method maxBy (and all other methods of Traversable ): 您可以实现scala.collection.Traversable然后可以使用maxBy方法(以及Traversable所有其他方法):

import scala.collection.Traversable

case class MyType(value: Int)
class MyCollection {
  def foreach(f: MyType => Unit): Unit = Seq(MyType(3), MyType(5), MyType(2)) foreach f
}

implicit class MyCollectionTraversable(c: MyCollection) extends Traversable[MyType] {
  override def foreach[U](f: MyType => U): Unit = c.foreach{e => f(e); ()}
}

Usage: 用法:

new MyCollection().maxBy{_.value}
// MyType = MyType(5)

You could also add implicit Ordering[MyType] like this: 您还可以像这样添加隐式Ordering[MyType]

import scala.math.Ordering
implicit val myTypeOrd = Ordering.by{ (_: MyType).value }

new MyCollection().max
// MyType = MyType(5)

Custom method 定制方法

You could also add your custom method max manually but even in this case MyCollectionTraversable will be useful: 您也可以手动添加自定义方法max ,但即使在这种情况下, MyCollectionTraversable也会很有用:

class MyCollectionTraversable(c: MyCollection) extends Traversable[MyType] {
  override def foreach[U](f: MyType => U): Unit = c.foreach{e => f(e); ()}
}

implicit class MyCollectionHelper(val c: MyCollection) extends AnyVal {
  def max: MyType = new MyCollectionTraversable(c).maxBy{_.value}
}

Usage: 用法:

new MyCollection().max
// MyType = MyType(5)

First, to get this out of the way: I feel that foreach is not the right method for this particular problem. 首先,要解决这个问题:我认为foreach不是解决此特定问题的正确方法。 Since it doesn't have a return value, the only way for it to yield a result is by side effects / mutability, which is generally seen as something to avoid in Scala. 由于它没有返回值,因此产生结果的唯一方法是副作用/易变性,这在Scala中通常被视为要避免的事情。 You should probably look into the reduce and fold methods, or their specialised min , max ... versions. 您可能应该研究reducefold方法,或它们专门的minmax ...版本。

If you're really intent on using foreach , you need to pass a closure to foreach that updates a free max variable maintained outside of its scope. 如果您确实打算使用foreach ,则需要将闭包传递给foreach以更新在其作用域之外维护的免费max变量。

This is off the cuff but should work: 这是袖手旁观,但应该可以:

def max: MyType = {
    var max = MyType(0)
    foreach {t =>
        if(t.value > max) max = t.value
    }
    max
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM