2012-06-19 73 views
22

我想分割一個元組,去掉最後兩個元素。我嘗試使用list drop/take方法,但我無法成功獲取元組。如何在scala中分片元組

這裏是我想盡了辦法:

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 = ??? 

我看到here該列表多元組沒有在斯卡拉(沒有?)可能的。

是否有其他方法來獲取該子傀儡(不處理myTuple._1,myTuple._2 ...)?

+4

我認爲這可以用[無形](https://github.com/milessabin/shapeless)'HList'完成。看看[這個問題](http://stackoverflow.com/questions/9028459/a-clean-way-to-combine-two-tuples-into-a-new-larger-tuple-in-scala)。 – incrop

回答

38

這是這種東西shapeless可以在通用方式做,涉及改建爲HList。首頁 - get shapeless。然後運行階與相關法的類型(在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. 

添加不成形到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" 

現在讓我們玩!

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

我們必須導入不成形

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

我們把我們的元組爲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 

然後我們採取的第一個4(注意:_4是一個類型參數,不是方法參數

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

現在變回一個元組

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

我們可以縮短這個:

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

本課程的推廣到一個N元組

+4

確保包含'-Ydependent-method-types',否則您將無法找到參數tupler的隱式值:shapeless.Tupler [take .Out]'(困惑了一會兒,試圖想出一個答案) –

+0

真棒的回答,並在下午!(法國時區:)) – iwalktheline

+0

無形2.00中的這種變化如何?無法讓它編譯 – 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

它的工作原理,但要求明確寫入模式匹配。我正在尋找一種方法來做到這一點,不管元組的長度。 – iwalktheline

+0

查看我的答案 - 我有一個完整工作的廣義示例,使用Miles Sabin的無形庫 –

3

第一M元素怎麼樣:

 

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

很棒:)我不知道元組是Product-s並且有可用的迭代器和arity –