2010-10-14 23 views
29

Có điều gì đó tương tự như the slice notation in Python trong Scala không?Ký hiệu slice ở Scala?

Tôi nghĩ đây thực sự là một hoạt động hữu ích nên được kết hợp trong tất cả các ngôn ngữ.

+2

Vâng, một số người thích một ngôn ngữ nhỏ, đơn giản và sạch sẽ. Không phải mọi đường cú pháp nhỏ đều đáng giá. – soc

+7

Tôi không tin rằng Scala là nhỏ và đơn giản mặc dù. So với một cái gì đó như lua, anyway ... –

+9

So sánh với Python Scala không quá nhỏ và đơn giản, nó có nhiều cấu trúc hơn Python. –

Trả lời

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) 

Điều này sẽ làm gì?

Tuyên bố từ chối trách nhiệm: Không được tổng quát đúng cách.


EDIT:

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) 
+0

gr8.can bạn sửa đổi nó để có tiêu cực và các bước cũng? – Emil

+0

bạn đang sử dụng scala nào? Tôi đang sử dụng 2.7.It nói 'IterableLike' không phải là thành viên của bộ sưu tập. – Emil

+0

cũng xin vui lòng giải thích code.i mới để scala. – Emil

7

Xem ScalaAPI here

Vì vậy, không thuận tiện cho ký hiệu tương tự, nhưng các hoạt động là có

def lát (từ: Int, cho đến khi: Int) : Seq [A]

Chọn một khoảng thời gian.

Chọn một khoảng thời gian.

Lưu ý: c.slice (từ đến) là tương đương (nhưng có thể hiệu quả hơn) c.drop (từ) .take (để - từ)

từ chỉ số những người đầu tiên trở lại trong chuỗi này. cho đến khi chỉ mục vượt qua phần tử được trả lại cuối cùng trong chuỗi này.

lợi nhuận

một chuỗi có chứa các yếu tố khởi điểm chỉ số từ và mở rộng lên đến (nhưng không bao gồm) chỉ số cho đến khi của dãy này.

lớp định nghĩa: IterableLike → TraversableLike

48

phương pháp tương đương trong Scala (với một cú pháp hơi khác nhau) tồn tại cho tất cả các loại trình tự:

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

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

Sự khác biệt lớn nhất so với cắt bằng Python là bắt đầu và kết thúc chỉ số là bắt buộc trong Scala.

+0

là quá tải của nhà điều hành có thể sử dụng nó như cú pháp python.I nghĩ rằng đó là thanh lịch hơn. – Emil

+4

Scala không có toán tử. – soc

2

Lưu ý rằng điều này không hoàn toàn làm việc bằng cách sử dụng apply, nhưng nó khái quát vào danh sách, chuỗi, mảng, vv:

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

Cách sử dụng là:

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) 

Bạn có thể muốn đổi tên phương thức thành một thứ khác phù hợp với bạn.Ngoại trừapply (vì đã có chuyển đổi từ String thành StringLike để trang trí chuỗi bằng phương pháp apply - tương tự với ArrayOps - và đã có phương pháp áp dụng trên các loại bộ sưu tập khác như List).

Cảm ơn bạn đã Daniel vì gợi ý sử dụng chế độ xem bị ràng buộc.