2012-06-19 37 views
22

Tôi đang cố gắng cắt một tuple, loại bỏ hai mục cuối cùng. Tôi đã thử sử dụng danh sách thả/lấy phương pháp nhưng tôi không thể thành công để có được một tuple trở lại.Làm thế nào để lát một tuple trong scala

Dưới đây là cách tiếp cận tôi đã cố gắng:

scala> val myTuple = (1, 2, 4, 5, 0, 5) 
myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5) 

scala> val myList = myTuple.productIterator.toList 
myList: List[Any] = List(1, 2, 4, 5, 0, 5) 

scala> val mySubList = myList.dropRight(2) 
mySubList: List[Any] = List(1, 2, 4, 5) 

scala> val mySubTuple = ??? 

tôi thấy here liệt kê để tuple không (chưa?) Có thể trong scala.

Có cách nào khác để nhận được subtuple đó (không xử lý myTuple._1, myTuple._2 ...) không?

+4

Tôi nghĩ rằng điều này có thể được thực hiện với [shapeless] (https://github.com/milessabin/shapeless) 'HList'. Hãy xem [câu hỏi này] (http://stackoverflow.com/questions/9028459/a-clean-way-to-combine-two-tuples-into-a-new-larger-tuple-in-scala). – incrop

Trả lời

38

Đây là loại điều mà shapeless có thể làm trong một generic cách, liên quan đến chuyển đổi thành một HList.

Đầu tiên - get shapeless. Sau đó chạy scala với các loại phương pháp phụ thuộc bật (theo mặc định trong 2.10):

C:\Scala\sdk\scala-2.9.2\bin>scala -Ydependent-method-types 
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_04). 
Type in expressions to have them evaluated. 
Type :help for more information. 

Thêm hình thù vào classpath:

scala> :cp C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar 
Added 'C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar'. Your new classpath is: 
"C:\tibco\tibrv\8.2\lib\tibrvnative.jar;C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar" 

Bây giờ chúng ta chơi!

scala> (1, 2.3, 'a, 'b', "c", true) 
res0: (Int, Double, Symbol, Char, java.lang.String, Boolean) = (1,2.3,'a,b,c,true) 

Chúng ta phải nhập khẩu hình thù

scala> import shapeless._; import Tuples._; import Nat._ 
import shapeless._ 
import Tuples._ 
import Nat._ 

Chúng tôi lần lượt tuple của chúng tôi vào một HList

scala> res0.hlisted 
res2: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char,shapeless.::[java.lang.String,shapeless.::[Boolean,shapeless.HNil]]]]]] = 1 :: 2.3 :: 'a :: b :: c :: true :: HNil 

Sau đó, chúng ta hãy là người đầu tiên 4 (lưu ý rằng _4 là một tham số kiểu, không phải là một đối số phương thức)

scala> res2.take[_4] 
res4: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char, shapeless.HNil]]]] = 1 :: 2.3 :: 'a :: b :: HNil 

Bây giờ chuyển đổi trở lại một tuple

scala> res4.tupled 
res5: (Int, Double, Symbol, Char) = (1,2.3,'a,b) 

Chúng ta có thể rút ngắn này:

val (a, b, c, d) = sixtuple.hlisted.take[_4].tupled 
//a, b, c and d would all have the correct inferred type 

Điều này tất nhiên khái quát đến M yếu tố đầu tiên của một N -tuple

+4

Hãy chắc chắn bao gồm '-Ydependent-method-types' hoặc bạn sẽ nhận được' không tìm thấy giá trị ngầm cho tham số tupler: shapeless.Tupler [take .Out] '(nhầm lẫn tôi trong một thời gian cố gắng để đưa ra một câu trả lời cho điều này) –

+0

câu trả lời tuyệt vời, và vào buổi chiều!(Múi giờ của Pháp :)) – iwalktheline

+0

Làm thế nào thay đổi này trong không có hình dạng 2.00? Không thể làm cho nó biên dịch – Edmondo1984

5
scala> val myTuple = (1, 2, 4, 5, 0, 5) 
myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5) 

scala> myTuple match { 
    | case (a, b, c, d, _, _) => (a, b, c, d) 
    | } 
res0: (Int, Int, Int, Int) = (1,2,4,5) 
+0

Nó hoạt động nhưng yêu cầu phải viết rõ ràng mẫu phù hợp. Tôi đang tìm một cách để làm điều đó bất kể độ dài của tuple. – iwalktheline

+0

Xem câu trả lời của tôi - Tôi có một ví dụ tổng quát đã được làm việc đầy đủ bằng cách sử dụng thư viện không định dạng của Miles Sabin –

3

thế nào về:

 

scala> val myTuple = (1,2,4,5,0,5) 
myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5) 

scala> val (left,right):Tuple2[List[Int],List[Int]] = myTuple.productIterator.toList.splitAt(myTuple.productArity - 2) 
left: List[Int] = List(1, 2, 4, 5) 
right: List[Int] = List(0, 5) 

scala> val mytuple2 = (right(0),right(1)) 
mytuple2: (Int, Int) = (0,5) 


+0

tuyệt vời :) Tôi không biết rằng bộ dữ liệu là Sản phẩm và có sẵn trình vòng lặp và có sẵn không –

Các vấn đề liên quan