2010-07-27 16 views
22

Soy nuevo en scala, y lo que estoy aprendiendo es tuple.Pregunta simple sobre la tupla de scala

puedo definir una tupla de la siguiente manera, y obtener los artículos:

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

Mi pregunta es:

  1. Cómo obtener la longitud de un par de valores?
  2. ¿Es la tupla mutable? ¿Puedo modificar sus artículos?
  3. ¿Hay alguna otra operación útil que podamos hacer en una tupla?

¡Gracias de antemano!

Respuesta

39

1] tuple.productArity

2] Nº

3] Algunas operaciones interesantes que se pueden realizar en tuplas: (REPL una sesión corta)

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 

Ver scaladocs de Tuple2, Tuple3 etc. para más.

+0

λ G, ¡gracias de nuevo! – Freewind

+0

@Freewind, ¡Bienvenido! – missingfaktor

4
  1. Conoces el tamaño de una tupla, es parte de su tipo. Por ejemplo, si se define una función def f(tup: (Int, Int)), usted sabe la longitud de tup es 2 ya que los valores de tipo (Int, Int) (también conocido como Tuple2[Int, Int]) siempre tienen una longitud de 2.
  2. En realidad no. Las tuplas son útiles para almacenar una cantidad fija de elementos de tipos posiblemente diferentes y pasarlos, ponerlos en estructuras de datos, etc. En realidad, no hay mucho que pueda hacer con ellos, aparte de crear tuplas y sacar cosas de las tuplas.
11

Tuples son inmutables, pero, al igual que todas las clases de los casos, tienen un método de copia que se puede utilizar para crear un nuevo Tuple con unos pocos elementos cambiados:

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

Una cosa que también se puede hacer con una tupla es extraer el contenido usando el match expresión:

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

Da:

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

gracias por este buen ejemplo – Freewind

5

Otro buen truco ad pregunta 3) (como 1 y 2 ya están contestadas por otros)

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

Editar: de hecho, es más bien una característica de las clases de coincidencia de patrones y casos, una tupla es sólo un ejemplo sencillo de una clase de caso ...

+0

gracias, útil – Freewind

4

1 y 2 ya han sido respondidas.

Una cosa muy útil que puede usar para tuplas es devolver más de un valor de un método o función.Un simple ejemplo:

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

cuanto a la pregunta 3:

Una cosa útil que puede hacer con tuplas es almacenar listas de parámetros para las funciones:

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

[Editar] Como señala Randall, que' Es mejor usar algo como esto en "la vida real":

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

Para extraer los valores de tuplas en el medio de una "cadena de transformación colección" se puede escribir:

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

nota de las llaves en torno al caso, los paréntesis no funcionarán.

+3

Tenga en cuenta que en esta construcción, va a sintetizar las versiones tupladas de la función que se levantó del método 'f' * en cada iteración del' foreach' *. –

1

Usando shapeless, usted puede fácilmente obtener una gran cantidad de métodos útiles, que están generalmente disponibles sólo en colecciones:

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] 

Todo lo que se escribe como cabría esperar (que es first tiene tipo String, concat tiene por tipo (String, Int, Boolean, Double, Double, Long) , etc.)

El último método anterior (.to[Collection]) debería estar disponible en la próxima versión (a partir de 2014/07/19).

También puede "actualizar" una tupla

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

sino que devolverá una nueva tupla en lugar de la mutación de la original.