23

タプルをスライスして、最後の2つのアイテムを削除しようとしています。リストのドロップ/テイクメソッドを使用しようとしましたが、タプルを取り戻すことができません。

これが私が試したアプローチです:

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

ここで、タプルへのリストは(まだ?)scalaでは不可能であることがわかりました。

そのサブタプルを取得する他の方法はありますか(myTuple._1、myTuple._2 ...を処理せずに)?

4

3 に答える 3

40

これは、シェイプレスが一般的な方法で実行できる種類のことであり、への変換が含まれます。HList

まず、形を崩します。次に、依存するメソッドタイプをオンにした状態でscalaを実行します(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.

クラスパスにシェイプレスを追加します。

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

もちろん、これはタプルの最初のM要素に一般化されますN

于 2012-06-19T11:12:40.240 に答える
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)
于 2012-06-19T09:54:07.473 に答える
5

どうですか:

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

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

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


于 2012-06-26T08:38:46.430 に答える