关于scala元组的简单问题

发布于 2024-09-12 07:17:09 字数 341 浏览 2 评论 0原文

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

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

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

我的问题是:

  1. 如何获取元组的长度?
  2. 元组是可变的吗?我可以修改它的项目吗?
  3. 我们还可以对元组执行其他有用的操作吗?

提前致谢!

I'm new to scala, and what I'm learning is tuple.

I can define a tuple as following, and get the items:

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

My question is:

  1. How to get the length of a tuple?
  2. Is tuple mutable? Can I modify its items?
  3. Is there any other useful operation we can do on a tuple?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

往日 2024-09-19 07:17:10

1] tuple.productArity

2] No.

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 等了解更多。

1] tuple.productArity

2] No.

3] Some interesting operations you can perform on tuples: (a short REPL session)

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

See scaladocs of Tuple2, Tuple3 etc for more.

初懵 2024-09-19 07:17:10

您还可以使用元组做的一件事是使用 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

One thing that you can also do with a tuple is to extract the content using the match expression:

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

Gives:

A pair  of strings: Hello Freewind
A triplet of ints: 1 2 3
柏林苍穹下 2024-09-19 07:17:10

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

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)

Tuples are immutable, but, like all cases classes, they have a copy method that can be used to create a new Tuple with a few changed elements:

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)
命比纸薄 2024-09-19 07:17:10

关于问题 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 }

注意大小写周围的大括号,圆括号不起作用。

Concerning question 3:

A useful thing you can do with Tuples is to store parameter lists for functions:

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

[Edit] As Randall remarks, you'd better use something like this in "real life":

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

In order to extract the values from tuples in the middle of a "collection transformation chain" you can write:

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

Note the curly braces around the case, parentheses won't work.

你怎么敢 2024-09-19 07:17:10

另一个不错的技巧广告问题3)(因为1和2已经被其他人回答了)

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

编辑:事实上,它是模式匹配和案例类的一个功能,元组只是案例类的一个简单示例......

Another nice trick ad question 3) (as 1 and 2 are already answered by others)

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

Edit: in fact it's rather a feature of pattern matching and case classes, a tuple is just a simple example of a case class...

記柔刀 2024-09-19 07:17:10
  1. 您知道元组的大小,它是元组类型的一部分。例如,如果您定义一个函数 def f(tup: (Int, Int)),则您知道 tup 的长度为 2,因为 (Int) 类型的值, Int) (又名 Tuple2[Int, Int])的长度始终为 2。
  2. 不。
  3. 并非如此。元组对于存储固定数量的可能不同类型的项目并传递它们、将它们放入数据结构等非常有用。除了创建元组和从元组中获取内容之外,您实际上不能用它们做太多事情。
  1. You know the size of a tuple, it's part of it's type. For example if you define a function def f(tup: (Int, Int)), you know the length of tup is 2 because values of type (Int, Int) (aka Tuple2[Int, Int]) always have a length of 2.
  2. No.
  3. Not really. Tuples are useful for storing a fixed amount of items of possibly different types and passing them around, putting them into data structures etc. There's really not much you can do with them, other than creating tuples, and getting stuff out of tuples.
凉风有信 2024-09-19 07:17:10

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

1 and 2 have already been answered.

A very useful thing that you can use tuples for is to return more than one value from a method or function. Simple example:

// 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
演多会厌 2024-09-19 07:17:10

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

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

Using shapeless, you easily get a lot of useful methods, that are usually available only on 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]

Everything is typed as one would expect (that is first has type String, concat has type (String, Int, Boolean, Double, Double, Long), etc.)

The last method above (.to[Collection]) should be available in the next release (as of 2014/07/19).

You can also "update" a tuple

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

but that will return a new tuple instead of mutating the original one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文