关于scala元组的简单问题

时间:2010-07-27 13:10:48

标签: scala tuples

我是scala的新手,我正在学习的是tuple

我可以将元组定义为如下,并获取项目:

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

我的问题是:

  1. 如何获得元组的长度?
  2. 元组是否可变?我可以修改它的项目吗?
  3. 我们可以对元组做什么其他有用的操作吗?
  4. 提前致谢!

8 个答案:

答案 0 :(得分:41)

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

请参阅Tuple2Tuple3等的scaladocs以获取更多信息。

答案 1 :(得分:17)

您还可以对元组执行的操作是使用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

答案 2 :(得分:11)

Tuples是不可变的,但是,与所有案例类一样,它们有一个复制方法,可用于创建一个带有一些更改元素的新Tuple

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)

答案 3 :(得分:7)

关于问题3:

使用Tuples可以做的一件有用的事情是存储函数的参数列表:

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 }

请注意案例周围的花括号,括号不起作用。

答案 4 :(得分:5)

另一个很好的技巧广告问题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 :(得分:4)

  1. 你知道一个元组的大小,它是它的类型的一部分。例如,如果您定义函数def f(tup: (Int, Int)),则表示tup的长度为2,因为类型(Int, Int)(又名Tuple2[Int, Int])的值始终为2。 / LI>
  2. 没有
  3. 不是。元组可用于存储可能不同类型的固定数量的项目并将它们传递,将它们放入数据结构等中。除了创建元组和从元组中获取元素之外,实际上除了它们之外没什么可做的。

答案 6 :(得分:4)

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

答案 7 :(得分:1)

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

但是这将返回一个新的元组,而不是改变原始元组。