【问题标题】:Simple question about tuple of scala关于scala元组的简单问题
【发布时间】:2010-07-27 13:10:48
【问题描述】:

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

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

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

我的问题是:

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

提前致谢!

【问题讨论】:

    标签: scala tuples


    【解决方案1】:

    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。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        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)
        

        【讨论】:

          【解决方案4】:

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

          [编辑] 正如 Randall 所说,你最好在“现实生活”中使用这样的东西:

          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 }
          

          注意大括号周围的花括号,括号不起作用。

          【讨论】:

          • 请注意,在此构造中,您将在 foreach 的每次迭代中合成从方法 f 中提取的函数的元组版本 .
          【解决方案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)
            }
          }
          

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

          【讨论】:

            【解决方案6】:
            1. 您知道元组的大小,它是其类型的一部分。例如,如果您定义一个函数 def f(tup: (Int, Int)),则您知道 tup 的长度为 2,因为 (Int, Int)(又名 Tuple2[Int, Int])类型的值的长度始终为 2。
            2. 没有。
            3. 并非如此。元组可用于存储固定数量的可能不同类型的项目并将它们传递,将它们放入数据结构等。除了创建元组和从元组中获取内容之外,你真的没有什么可以做的。李>

            【讨论】:

              【解决方案7】:

              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
              

              【讨论】:

                【解决方案8】:

                使用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 年 7 月 19 日)。

                你也可以“更新”一个元组

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

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

                【讨论】:

                  猜你喜欢
                  • 2011-09-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-07
                  • 1970-01-01
                  • 2011-02-09
                  • 1970-01-01
                  • 2011-07-22
                  • 2011-08-19
                  相关资源
                  最近更新 更多