I have some collection, that implements def foreach(f: MyType => Unit): Unit
.
MyType
has member val value: Int
that is greater or equals to zero in normal case.
How coud i find element with maximum value
using foreach
?
UPD:
There should be method def max: MyType
within MyType
implementing this logic.
You could implement scala.collection.Traversable
- then you could use method maxBy
(and all other methods of 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:
import scala.math.Ordering
implicit val myTypeOrd = Ordering.by{ (_: MyType).value }
new MyCollection().max
// MyType = MyType(5)
You could also add your custom method max
manually but even in this case MyCollectionTraversable
will be useful:
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. 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. You should probably look into the reduce
and fold
methods, or their specialised min
, max
... versions.
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.
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
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.