Scala中的切片表示法?

时间:2010-10-14 11:20:43

标签: python scala slice

Scala中是否有与the slice notation in Python类似的内容?

我认为这是一个非常有用的操作,应该包含在所有语言中。

4 个答案:

答案 0 :(得分:50)

Scala中的等效方法(语法略有不同)适用于所有类型的序列:

scala> "Hello world" slice(0,4)
res0: String = Hell

scala> (1 to 10) slice(3,5)
res1: scala.collection.immutable.Range = Range(4, 5)

与Python中的切片相比,最大的区别是Scala中必须使用开始和结束索引。

答案 1 :(得分:20)

scala> import collection.IterableLike
import collection.IterableLike

scala> implicit def pythonicSlice[A, Repr](coll: IterableLike[A, Repr]) = new {
     |   def apply(subrange: (Int, Int)): Repr = coll.slice(subrange._1, subrange._2)
     | }
pythonicSlice: [A,Repr](coll: scala.collection.IterableLike[A,Repr])java.lang.Object{def apply(subrange: (Int, Int)): Repr}

scala> val list = List(3, 4, 11, 78, 3, 9)
list: List[Int] = List(3, 4, 11, 78, 3, 9)

scala> list(2 -> 5)
res4: List[Int] = List(11, 78, 3)
这会吗?

免责声明:未正确概括。


修改

scala> case class PRange(start: Int, end: Int, step: Int = 1)
defined class PRange

scala> implicit def intWithTildyArrow(i: Int) = new {
     |   def ~>(j: Int) = PRange(i, j)
     | }
intWithTildyArrow: (i: Int)java.lang.Object{def ~>(j: Int): PRange}

scala> implicit def prangeWithTildyArrow(p: PRange) = new {
     |   def ~>(step: Int) = p.copy(step = step)
     | }
prangeWithTildyArrow: (p: PRange)java.lang.Object{def ~>(step: Int): PRange}

scala> implicit def pSlice[A](coll: List[A]) = new {
     |   def apply(prange: PRange) = {
     |     import prange._
     |     coll.slice(start, end).grouped(step).toList.map(_.head)
     |   }
     | }
pSlice: [A](coll: List[A])java.lang.Object{def apply(prange: PRange): List[A]}

scala> val xs = List.range(1, 10)
xs: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> xs(3 ~> 9)
res32: List[Int] = List(4, 5, 6, 7, 8, 9)

scala> xs(3 ~> 9 ~> 2)
res33: List[Int] = List(4, 6, 8)

答案 2 :(得分:8)

请参阅ScalaAPI here

所以不一样的符号方便,但操作就在那里

  

def slice(from:Int,until:Int)   :Seq [A]

     

选择元素间隔。

     

选择元素间隔。

     

注意:c.slice(from,to)是等效的   到(但可能更有效)   c.drop(from).take(to - from)

     

来自此序列中第一个返回元素的索引。直到   索引一个超过此序列中最后一个返回的元素。

     

返回

     

包含从索引和扩展开始的元素的序列   直到(但不包括)索引直到   这个序列。

     

定义类:IterableLike→   TraversableLike

答案 3 :(得分:2)

请注意,使用apply并不是很有效,但概括到列表,字符串,数组等:

implicit def it2sl[Repr <% scala.collection.IterableLike[_, Repr]](cc: Repr) = new {
  def ~>(i : Int, j : Int) : Repr = cc.slice(i,j)
}

用法是:

scala> "Hello World" ~> (3, 5)
res1: java.lang.String = lo

scala> List(1, 2, 3, 4) ~> (0, 2)
res2: List[Int] = List(1, 2)

scala> Array('a', 'b', 'c', 'd') ~> (1, 3)
res3: Array[Char] = Array(b, c)

您可能希望将该方法重命名为其他您喜欢的方法。 apply除外(因为已经有StringStringLike的转换,它使用apply方法修饰字符串 - 与{{1}类似 - 并且已经有其他集合类型的apply方法,例如ArrayOps)。

感谢 Daniel 提示使用视图绑定。