web-dev-qa-db-ja.com

scalaのタプルについての簡単な質問

私はscalaを初めて使用し、私が学んでいるのはTupleです。

タプルを次のように定義して、アイテムを取得できます。

val Tuple = ("Mike", 40, "New York")
println("Name: " + Tuple._1)
println("Age: " + Tuple._2)
println("City: " + Tuple._3)

私の質問は:

  1. タプルの長さを取得するにはどうすればよいですか?
  2. タプルは変更可能ですか?アイテムを変更できますか?
  3. タプルに対して実行できる他の便利な操作はありますか?

前もって感謝します!

23
Freewind

1] Tuple.productArity

2]いいえ。

3]タプルで実行できるいくつかの興味深い操作:(短いREPLセッション)

scala> val x = (3, "hello")
x: (Int, Java.lang.String) = (3,hello)

scala> x.swap
res0: (Java.lang.String, Int) = (hello,3)

scala> x.toString
res1: Java.lang.String = (3,hello)

scala> val y = (3, "hello")
y: (Int, Java.lang.String) = (3,hello)

scala> x == y
res2: Boolean = true

scala> x.productPrefix
res3: Java.lang.String = Tuple2

scala> val xi = x.productIterator
xi: Iterator[Any] = non-empty iterator

scala> while(xi.hasNext) println(xi.next)
3
hello

詳細については、 Tuple2Tuple などのscaladocsを参照してください。

41
missingfaktor

タプルを使用して実行できることの1つは、match式を使用してコンテンツを抽出することです。

def tupleview( tup: Any ){
  tup match {
    case (a: String, b: String) =>
      println("A pair  of strings: "+a + " "+ b)
    case (a: Int, b: Int, c: Int) =>
      println("A triplet of ints: "+a + " "+ b + " " +c)
    case _ => println("Unknown")
  }
}

tupleview( ("Hello", "Freewind"))
tupleview( (1,2,3))

与える:

A pair  of strings: Hello Freewind
A triplet of ints: 1 2 3
17
olle kullberg

Tuplesは不変ですが、すべてのケースクラスと同様に、いくつかの要素が変更された新しいTupleを作成するために使用できるcopyメソッドがあります。

scala> (1, false, "two")
res0: (Int, Boolean, Java.lang.String) = (1,false,two)

scala> res0.copy(_2 = true)
res1: (Int, Boolean, Java.lang.String) = (1,true,two)

scala> res1.copy(_1 = 1f)
res2: (Float, Boolean, Java.lang.String) = (1.0,true,two)
11
retronym

質問3について:

タプルを使用して実行できる便利なことは、関数のパラメーターリストを格納することです。

def f(i:Int, s:String, c:Char) = s * i + c
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println((f _).tupled(t)))
//--> chachacha!
//--> borabora.

[編集]ランドールが述べているように、「実生活」では次のようなものを使用したほうがよいでしょう。

def f(i:Int, s:String, c:Char) = s * i + c
val g = (f _).tupled
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println(g(t)))

「コレクション変換チェーン」の途中にあるタプルから値を抽出するには、次のように記述します。

val words = List((3, "cha"),(2, "bora")).map{ case(i,s) => s * i }

ケースの周りの中括弧に注意してください。括弧は機能しません。

7
Landei

別の素敵なトリック広告の質問3)(1と2はすでに他の人によって回答されているため)

val Tuple = ("Mike", 40, "New York")
Tuple match  {
  case (name, age, city) =>{
    println("Name: " + name)
    println("Age: " + age)
    println("City: " + city)
  }
}

編集:実際、これはパターンマッチングとケースクラスの機能であり、タプルはケースクラスの単純な例にすぎません...

5
Sandor Murakozi

1と2はすでに回答済みです。

タプルを使用できる非常に便利なことは、メソッドまたは関数から複数の値を返すことです。簡単な例:

// Get the min and max of two integers
def minmax(a: Int, b: Int): (Int, Int) = if (a < b) (a, b) else (b, a)

// Call it and assign the result to two variables like this:
val (x, y) = minmax(10, 3)     // x = 3, y = 10
4
Jesper
  1. タプルのサイズを知っています、それはそのタイプの一部です。たとえば、関数def f(tup: (Int, Int))を定義する場合、タイプ(Int, Int)(別名Tuple2[Int, Int])の値の長さは常に2であるため、tupの長さは2であることがわかります。 2.2。
  2. 番号。
  3. あんまり。タプルは、さまざまなタイプのアイテムを一定量保存して渡したり、データ構造に入れたりするのに便利です。タプルを作成し、タプルからデータを取得する以外に、タプルでできることはほとんどありません。
4
sepp2k

shapeless を使用すると、通常はコレクションでのみ使用できる多くの便利なメソッドを簡単に取得できます。

import shapeless.syntax.std.Tuple._

val t = ("a", 2, true, 0.0)

val first = t(0)
val second = t(1)
// etc

val head = t.head
val tail = t.tail
val init = t.init
val last = t.last

val v = (2.0, 3L)

val concat = t ++ v
val append = t :+ 2L
val prepend = 1.0 +: t

val take2 = t take 2
val drop3 = t drop 3

val reverse = t.reverse

val Zip = t Zip (2.0, 2, "a", false)
val (unzip, other) = Zip.unzip

val list = t.toList
val array = t.toArray
val set = t.to[Set]

すべてが期待どおりに入力されます(つまり、firstのタイプはStringconcatのタイプは(String, Int, Boolean, Double, Double, Long)など)

上記の最後のメソッド(.to[Collection])次のリリースで利用可能になるはずです(2014/07/19現在)。

タプルを「更新」することもできます

val a = t.updatedAt(1, 3) // gives ("a", 3, true, 0.0)

ただし、元のタプルを変更する代わりに、新しいタプルが返されます。

1