I wasn't sure if groupBy
, takeWhile
, or grouped
would achieve what I wanted to do. I need to develop a function that automatically groups a list of numbers according to the interval I want to specify. The use case is taking a list of ages and sorting them into dynamic age categories (like 1-5, 5-10, etc.). It would need to be dynamic since the user may want to change the intervals.
For example, I have the list of numbers: List(103, 206, 101, 111, 211, 234, 242, 99)
I can interval by 10
, or by 100
. Then the result of an input of 100
would be: List(List(99),List(101,103,111),List(206,211,234,242))
.
I searched Google and SO for the last hour but couldn't find anything. Thanks for the help!
You will want groupBy
:
val xs = List(103, 206, 101, 111, 211, 234, 242, 99)
xs.groupBy(_ / 100)
// Map(0 -> List(99), 1 -> List(103, 101, 111), ...)
grouped
just creates subsequent clumps of a given size, not looking at the actual elements. takeWhile
just takes the leading elements as long as a predicate holds.
You can use the withDefaultValue
method on the resulting map to make it appear as an indexed sequence, where some entries are empty:
val ys = xs.groupBy(_ / 100) withDefaultValue Nil
ys(0) // List(99)
ys(4) // List() !
Here's an approach that generates the ranges and filters for values within them. I think the l.groupBy(_ / 100).values
is preferable though.
val interval = 100
//This gives List(Vector(0, 100), Vector(100, 200), Vector(200, 300))
val intervals = 0 until l.max + interval by interval sliding(2)
for(interval <- intervals;
within <- List(l.filter(x => x > interval(0) && x <= interval(1)))
) yield within
With val l = List(103, 206, 101, 111, 211, 234, 242, 99)
this gives:
List[List[Int]] = List(List(99), List(103, 101, 111), List(206, 211, 234, 242))
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.