0
votes

I want to define a function, that can cut a Seq of "something" based on pairs. for example in python, I can write like this:

def divide(lst, pairs):
    "each pair in pairs is a (base,upper) tuple"
    return [lst[b:u] for b, u in pairs]

>>> divide([1,2,3,4,5,6], [(0, 3), (3, 6)])
[[1, 2, 3], [4, 5, 6]]
>>> divide("abcdef", [(0, 3), (3, 6)])
['abc', 'def']

Thanks to the dynamic feature of python, this function can divide anything that can be sliced.

In scala, a naive version (can only divide Seq[Int]) is:

def divide(lst:Seq[Int], pairs:Seq[(Int, Int)]) = {
    pairs.map{case (b, u) => lst.slice(b,u)}
}

scala> divide(Seq(1,2,3,4,5,6), Seq((0, 3), (3, 6)))
result: Seq[Seq[Int]] = List(List(1, 2, 3), List(4, 5, 6))

What should I write if I want a divide function that support not only Seq[Int] but also Seq[T] for example Seq[Seq[Int]] at the same time?

I tried

def divide(lst:Seq[T], pairs:Seq[(Int, Int)]):Seq[Seq[T]] = {
    pairs.map{case (b, u) => lst.slice(b,u)}
}

but it doesn't compile.

----------Update----------

Another problem is if I pass a mutable.Seq as lst, finally I will get a Seq(immutable).

for example

scala> divide(Array(1,2,3,4,5,6), Seq((0, 2), (2, 4), (4, 6)))
result: Seq[Seq[Int]] = ArrayBuffer(WrappedArray(1, 2), WrappedArray(3, 4), WrappedArray(5, 6))

I know the problem is that the lst is declared as Seq so it returns a Seq. How can I declare a function that can handle different subclasses of Seq?

1

1 Answers

6
votes

You need to define the type T upfront.

def divide[T](lst:Seq[T], pairs:Seq[(Int, Int)]):Seq[Seq[T]] = {
    pairs.map{case (b, u) => lst.slice(b,u)}
}