Scala version of Rubys' each_slice?
Asked Answered
A

2

8

Does Scala have a version of Rubys' each_slice from the Array class?

Aborticide answered 16/3, 2010 at 16:16 Comment(0)
W
12

Scala 2.8 has grouped that will chunk the data in blocks of size n (which can be used to achieve each_slice functionality):

scala> val a = Array(1,2,3,4,5,6)
a: Array[Int] = Array(1, 2, 3, 4, 5, 6)

scala> a.grouped(2).foreach(i => println(i.reduceLeft(_ + _)) )
3
7
11

There isn't anything that will work out of the box in 2.7.x as far as I recall, but it's pretty easy to build up from take(n) and drop(n) from RandomAccessSeq:

def foreach_slice[A](s: RandomAccessSeq[A], n: Int)(f:RandomAccessSeq[A]=>Unit) {
  if (s.length <= n) f(s)
  else {
    f(s.take(n))
    foreach_slice(s.drop(n),n)(f)
  }
}

scala> val a = Array(1,2,3,4,5,6)
a: Array[Int] = Array(1, 2, 3, 4, 5, 6)

scala> foreach_slice(a,2)(i => println(i.reduceLeft(_ + _)) )                 
3
7
11
Wilkens answered 16/3, 2010 at 16:37 Comment(4)
It would be better to create an Array wrapper class, which used the original Array as the back-end while presently only a slice of it. An implicit eachSlice method could then be added to Array, returning a List[ArraySlice]. Don't you want to have a go at it in your answer? :-) I can't give you more votes, but I'd admire you. :-) :-)Pronoun
@Daniel: Hahaha--yes that would be better (faster), but if it's not going in a library somewhere (and why would it since we already have grouped in 2.8?), I think I'll leave it as an exercise for the reader.Wilkens
It would work better for in-place algorithms. You can always submit it for enhancement to Scala. Better sign up the contributor form first, though. I'd like to see such an option available.Pronoun
Maybe I will after @specialized is pushed through the library a bit more than it is now. Otherwise the boxing/unboxing overhead will swamp everything for primitive types anyway.Wilkens
O
6

Tested with Scala 2.8:

scala> (1 to 10).grouped(3).foreach(println(_))
IndexedSeq(1, 2, 3)
IndexedSeq(4, 5, 6)
IndexedSeq(7, 8, 9)
IndexedSeq(10)
Operate answered 16/3, 2010 at 16:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.