Reputation: 2531
case class DataItem(name: String, timestamp: Long, value: String)
val dataitems = List(DataItem(SpindleSpeed, 1223334444, 20.3333),
DataItem(SpindleSpeed, 1223334450, 21.3333),
DataItem(SpindleSpeed, 1223334460, 19.3333),
DataItem(Load, 1223334444, 70.0023),
DataItem(Load, 1223334446, 72.0023),
DataItem(Pressure, 1223334444, 20.3333))
I have a list somewhat like this, I need to filter out the dataitems which has the lowest timestamp
. There can be more than one dateitems having the same timestamp, in that case I need all those dataitems.
In the above case, I expect the filtered list to be,
List(DataItem(SpindleSpeed, 1223334444, 20.3333),
DataItem(Load, 1223334444, 70.0023),
DataItem(Pressure, 1223334444, 20.3333))
What is the functional way of doing it? I tried sorting the list and returning the head. But that returns only a single dataitem which doesn't seem to right.
Upvotes: 0
Views: 180
Reputation: 167901
It's easy to do it in two passes:
val least = dataitems.minBy(_.timestamp).timestamp
val smalls = dataitems.filter(_.timestamp == least)
It is less fun to do it in one pass:
(List[DataItem]() /: dataitems){ (xs,x) => xs match {
case Nil => x :: Nil
case x0 :: more =>
if (x0.timestamp < x.timestamp) xs
else if (x0.timestamp > x.timestamp) x :: Nil
else x :: x0
}}
These are both more efficient than grouping everything by timestamp and then throwing all but the first away.
Upvotes: 3
Reputation: 92056
scala> val SpindleSpeed = "S"
SpindleSpeed: java.lang.String = S
scala> val Pressure = "P"
Pressure: java.lang.String = P
scala> val Load = "L"
Load: java.lang.String = L
scala> case class DataItem(name: String, timestamp: Long, value: Double)
defined class DataItem
scala> val dataitems = List(DataItem(SpindleSpeed, 1223334444, 20.3333),
| DataItem(SpindleSpeed, 1223334450, 21.3333),
| DataItem(SpindleSpeed, 1223334460, 19.3333),
| DataItem(Load, 1223334444, 70.0023),
| DataItem(Load, 1223334446, 72.0023),
| DataItem(Pressure, 1223334444, 20.3333))
dataitems: List[DataItem] = List(DataItem(S,1223334444,20.3333), DataItem(S,1223334450,21.3333), DataItem(S,1223334460,19.3333), DataItem(L,1223334444,70.0023), DataItem(L,1223334446,72.0023), DataItem(P,1223334444,20.3333))
scala> dataitems.groupBy(_.timestamp).minBy(_._1)._2
res2: List[DataItem] = List(DataItem(S,1223334444,20.3333), DataItem(L,1223334444,70.0023), DataItem(P,1223334444,20.3333))
scala>
Upvotes: 4