2010-07-27 28 views
22

Tôi mới dùng scala và những gì tôi đang học là tuple.Câu hỏi đơn giản về tuple of scala

tôi có thể xác định một tuple như sau, và nhận được các mục:

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

Câu hỏi của tôi là:

  1. Làm thế nào để có được chiều dài của một tuple?
  2. Tuple có thể thay đổi không? Tôi có thể sửa đổi các mục của nó không?
  3. Có hoạt động hữu ích nào khác mà chúng tôi có thể thực hiện đối với một bộ dữ liệu không?

Cảm ơn bạn trước!

Trả lời

39

1] tuple.productArity

2] số

3] Một số hoạt động thú vị mà bạn có thể thực hiện trên các bộ: (a phiên REPL ngắn)

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 

Xem scaladocs của Tuple2, Tuple3 v.v.

+0

λ G, cảm ơn bạn một lần nữa! – Freewind

+0

@Freewind, Chào mừng bạn! – missingfaktor

4
  1. Bạn biết kích thước của một bộ túp, đó là một phần của loại đó. Ví dụ nếu bạn định nghĩa một hàm def f(tup: (Int, Int)), bạn biết chiều dài của tup là 2 vì giá trị của loại (Int, Int) (aka Tuple2[Int, Int]) luôn luôn có một chiều dài 2.
  2. số
  3. Không thực sự. Tuples rất hữu ích cho việc lưu trữ một số lượng cố định của các loại có thể khác nhau và chuyển chúng xung quanh, đưa chúng vào cấu trúc dữ liệu, vv Thực sự không có nhiều bạn có thể làm với chúng, ngoài việc tạo tuple, và lấy ra khỏi các bộ dữ liệu.
11

Tuples là không thay đổi, nhưng cũng như mọi tầng lớp trường hợp, họ có một phương pháp sao chép có thể được sử dụng để tạo ra một mới Tuple với một vài thay đổi các yếu tố:

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

Một điều mà bạn cũng có thể làm với một tuple là để trích xuất nội dung bằng cách sử dụng biểu 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)) 

Cung cấp:

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

cảm ơn cho ví dụ tốt đẹp này – Freewind

5

Một thủ thuật rất hay câu hỏi quảng cáo 3) (như 1 và 2 đã được trả lời bởi những người khác)

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

Chỉnh sửa: trên thực tế nó khá một tính năng của mô hình kết hợp và trường hợp lớp học, một tuple chỉ là một ví dụ đơn giản của một trường hợp ...

+0

cảm ơn bạn, hữu ích – Freewind

4

1 và 2 đã được trả lời.

Điều rất hữu ích mà bạn có thể sử dụng bộ dữ liệu là trả lại nhiều giá trị từ một phương thức hoặc hàm.ví dụ đơn giản:

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

Về câu hỏi 3:

Một điều hữu ích mà bạn có thể làm với Tuples là để lưu trữ danh sách tham số cho các chức năng:

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

[Chỉnh sửa] Như nhận xét của Randall, bạn' d sử dụng tốt hơn một cái gì đó như thế này trong "cuộc sống thực":

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

Để trích xuất các giá trị từ các bộ dữ liệu ở giữa "chuỗi chuyển đổi bộ sưu tập", bạn có thể viết:

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

Lưu ý các dấu ngoặc nhọn xung quanh vỏ, dấu ngoặc đơn sẽ không hoạt động.

+3

Lưu ý rằng trong cấu trúc này, bạn sẽ tổng hợp các phiên bản của hàm được tự nâng lên từ phương thức 'f' * trên mỗi lần lặp của' foreach' *. –

1

Sử dụng shapeless, bạn dễ dàng nhận được rất nhiều phương pháp hữu ích, mà thường chỉ có sẵn trên các bộ sưu tập:

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] 

Tất cả mọi thứ được gõ như người ta mong đợi (có nghĩa là first có kiểu String, concat có kiểu (String, Int, Boolean, Double, Double, Long) , vv)

Phương pháp cuối cùng ở trên (.to[Collection]) sẽ có sẵn trong bản phát hành tiếp theo (kể từ 2014/07/19).

Bạn cũng có thể "cập nhật" một tuple

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

nhưng điều đó sẽ trả về một tuple mới thay vì đột biến một bản gốc.

Các vấn đề liên quan