2010-07-27 8 views
22

Je suis nouveau à Scala, et ce que j'apprends est tuple.Simple question sur tuple de scala

Je peux définir un tuple comme suit, et obtenir les articles:

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

Ma question est:

  1. Comment obtenir la longueur d'un tuple?
  2. Le tuple est-il mutable? Puis-je modifier ses éléments?
  3. Y at-il une autre opération utile que nous pouvons faire sur un tuple?

Merci d'avance!

Répondre

39

1] tuple.productArity

2] Non

3] Certaines opérations intéressantes que vous pouvez effectuer sur tuples: (une courte séance de 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 

Voir scaladocs de Tuple2, Tuple3 etc. pour plus.

+0

λ G, merci encore! – Freewind

+0

@Freewind, Bienvenue! – missingfaktor

4
  1. Vous connaissez la taille d'un tuple, cela fait partie de son type. Par exemple, si vous définissez une fonction def f(tup: (Int, Int)), vous connaissez la longueur de tup est 2 parce que les valeurs de type (Int, Int) (aka Tuple2[Int, Int]) ont toujours une longueur de 2.
  2. No.
  3. Pas vraiment. Les tuples sont utiles pour stocker une quantité fixe d'éléments de types différents et les transmettre, les placer dans des structures de données, etc. Vous ne pouvez pas vraiment faire grand-chose avec eux, sauf pour créer des tuples et extraire des tuples.
11

Tuples sont immuables, mais, comme toutes les classes de cas, ils ont une méthode de copie qui peut être utilisé pour créer une nouvelle Tuple avec quelques éléments changé:

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) 
17

Une chose que vous pouvez faire avec un tuple est d'extraire le contenu en utilisant l'expression 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)) 

donne:

A pair of strings: Hello Freewind 
A triplet of ints: 1 2 3 
+0

merci pour ce bel exemple – Freewind

5

Une autre question ad truc agréable 3) (comme 1 et 2 sont déjà répondu par d'autres)

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

Edit: en fait, il est plutôt une caractéristique des classes de correspondance de modèle et cas, un tuple est juste un exemple simple d'une classe de cas ...

+0

merci, utile – Freewind

4

1 et 2 ont déjà été répondu.

Une chose très utile que vous pouvez utiliser pour les tuples est de renvoyer plus d'une valeur d'une méthode ou d'une fonction.Exemple simple:

// 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 
7

En ce qui concerne la question 3:

Une chose utile que vous pouvez faire avec Tuples est de stocker des listes de paramètres pour les fonctions:

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

[Modifier] Comme le remarque Randall, vous d mieux utiliser quelque chose comme ça dans la "vraie vie":

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

Pour extraire les valeurs de tuples au milieu d'une « chaîne de transformation de collection » vous pouvez écrire:

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

Notez les accolades dans le cas, entre parenthèses ne fonctionnera pas.

+3

Notez que dans cette construction, vous allez synthétiser les versions triées de la fonction elle-même levée de la méthode 'f' * à chaque itération de' foreach' *. –

1

En utilisant shapeless, vous obtenez facilement un grand nombre de méthodes utiles, qui ne sont généralement disponibles que sur les collections:

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] 

Tout est typé comme on pouvait s'y attendre (c'est first est de type String, concat a le type (String, Int, Boolean, Double, Double, Long) , etc.)

La dernière méthode ci-dessus (.to[Collection]) devrait être disponible dans la prochaine version (en date du 2014/07/19).

Vous pouvez également « mettre à jour » un tuple

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

mais qui retourne un nouveau tuple au lieu de muter l'original.