Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala filter on a list by index

I wanted to write it functionally, and the best I could do was:

list.zipWithIndex.filter((tt:Tuple2[Thing,Int])=>(tt._2%3==0)).unzip._1

to get elements 0, 3, 6,...

Is there a more readable Scala idiom for this?

like image 404
user833970 Avatar asked Sep 15 '13 16:09

user833970


3 Answers

If efficiency is not an issue, you could do the following:

list.grouped(3).map(_.head)

Note that this constructs intermediate lists.

Alternatively you can use a for-comprehension:

for {
  (x,i) <- list zipWithIndex
  if i % 3 == 0
} yield x

This is of course almost identical to your original solution, just written differently.

My last alternative for you is the use of collect on the zipped list:

list.zipWithIndex.collect {
  case (x,i) if i % 3 == 0 => x
}
like image 165
gzm0 Avatar answered Oct 13 '22 23:10

gzm0


Not much clear, but still:

xs.indices.collect { case i if i % 3 == 0 => xs(i) }
like image 39
om-nom-nom Avatar answered Oct 13 '22 22:10

om-nom-nom


A nice, functional solution, without creating temporary vectors, lists, and so on:

def everyNth[T](xs: List[T], n:Int): List[T] = xs match {
  case hd::tl => hd::everyNth(tl.drop(n-1), n)
  case Nil => Nil
}
like image 5
Karol S Avatar answered Oct 13 '22 21:10

Karol S