Scala中是否有类似于Python 中的切片表示法的东西?
我认为这确实是一个有用的操作,应该包含在所有语言中。
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 中开始和结束索引是强制性的。
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)
在此处查看ScalaAPI
所以不一样的符号方便,但操作是有的
def slice (from: Int, until: Int) : Seq[A]
选择元素的间隔。
选择元素的间隔。
注意:c.slice(from, to) 等价于(但可能比)c.drop(from).take(to - from)
从这个序列中第一个返回元素的索引开始。直到索引超过此序列中最后一个返回的元素。
返回
包含从 index from 开始并一直延伸到(但不包括) index until 该序列的元素的序列。
定义类:IterableLike → TraversableLike
请注意,这并不完全适用于 using 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
(因为已经有一个转换 from String
to StringLike
which 用方法装饰 String apply
- 与 - 类似ArrayOps
- 并且在其他集合类型上已经有一个 apply 方法,例如List
)。
感谢Daniel提示使用视图绑定。