2012-04-01 63 views
5

Tôi có List[(String,String)] và tôi cần phải sắp xếp chúng theo giá trị thứ 2 và trả về một bản đồSắp xếp đồ theo giá trị

Tôi đã làm như sau:

val newMap = list.sortBy(_._2).foldLeft(Map.empty[String, String]) { 
     (map, key) ⇒ map + (key._1 → key._2) 
    } 

danh sách là một List[(String,String)]

Tuy nhiên bản đồ trả lại không được sắp xếp !!

+3

Tôi nghĩ bạn nên nêu rõ lý do tại sao bạn cần trả lại một "Bản đồ" và ý nghĩa của nó được sắp xếp mà bạn quan tâm. Ví dụ; sau đó bạn có muốn thêm cặp khóa-giá trị bổ sung không? –

Trả lời

9

Mặc định Map triển khai dựa trên cơ sở băm và chúng không giữ nguyên thứ tự. Thay vì sử dụng scala.collection.mutable.LinkedHashMap:

val newMap = list.sortBy(_._2).foldLeft(new LinkedHashMap[String, String]) { 
    (map, key) => map += (key._1 -> key._2) 
    map 
} 

Theo đề nghị của @Rex Kerr, scala.collection.immutable.ListMap có thể là một lựa chọn tốt hơn cho loại mục tiêu:

val newMap = list.sortBy(_._2).foldLeft(new ListMap[String, String]) { 
    (map, key) => map + (key._1 -> key._2) 
} 

Hoặc (một lần nữa đầy đủ các khoản tín dụng nên đến @Rex Kerr):

val newMap = new ListMap() ++ list.sortBy(_._2) 

Tuy nhiên bạn thực sự muốn đạt được điều gì? Hình như bạn có thể lựa chọn cấu trúc dữ liệu sai ...

+0

Tôi không đồng ý với câu trả lời này vì nó gây hiểu nhầm: bạn đang trả về cấu trúc có thể thay đổi được ** không được sắp xếp ở alll **. Nó chỉ đơn giản là * đi ngang trong thứ tự chèn * –

+2

@oxbow_lakes: Tôi nghĩ đây chính xác là những gì OP yêu cầu (dựa trên mã mẫu) - có một 'Bản đồ' từ' khóa' -> 'giá trị' nhưng với các mục được sắp xếp theo' giá trị' . Tuy nhiên hãy để OP quyết định câu trả lời nào là chính xác hoặc rõ ràng. BTW tôi đã không downvoted câu trả lời của bạn trong trở lại, để được rõ ràng ;-). –

+0

Các mục nhập không được "sắp xếp" - chúng có thể đi ngang theo thứ tự có thể dự đoán được. Đây không phải là điều tương tự –

2

giả định của tôi từ câu hỏi của bạn (mà không phải là 100% rõ ràng): bạn muốn có một Map[A, B] được sắp xếp theo B

Đây là không thể; Bản đồ scala được sắp xếp là SortedMap[A, B] và điều này phải được sắp xếp theo một số thứ tự trên loại A.

Nếu tất cả các bạn muốn là một chuỗi traversable các cặp (A, B) theo B, sau đó bạn không có nhu cầu về một Map và giải pháp:

list sortBy (_._2) 

... sẽ đủ. Nếu bạn muốn có một số Map thì câu hỏi của Tomasz có vẻ hấp dẫn - nhưng nó gây hiểu lầm. Bản đồ là không được sắp xếp; nó có thể đi qua theo thứ tự đã biết (thứ tự chèn). Đây là không giống nhau - các lần bổ sung tiếp theo vào Bản đồ sẽ xuất hiện ở cuối (từ góc nhìn ngang) bất kể giá trị là gì. Vì vậy, tôi nghĩ rằng bạn cần phải tự hỏi mình một câu hỏi: tôi đang cố gắng làm gì?

Nếu bạn quan tâm đến việc duyệt qua một chuỗi các cặp theo phần tử thứ hai, bạn không cần một Bản đồ.

+0

Tôi đã làm rõ những gì tôi đã giả định OP đang cố gắng làm (tức là tạo một 'SortedMap [A, B]' được sắp xếp theo 'B') và sau đó giải thích tại sao điều này là không thể –

1

này nên càng đơn giản như:

val input = List((1,1), (3,4), (20,19), (2,2)) 
val output = input.sortBy(_._2).toMap 

đầu ra là:

Map (1-> 1, 2-> 2, 3> 4, 20-> 19)

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