2010-07-24 30 views
6

Trong Python, một cuốn từ điển có thể được xây dựng từ một bộ sưu tập iterable của các bộ:Scala - làm thế nào để xây dựng một bản đồ bất biến từ một bộ sưu tập của Tuple2?

>>> listOfTuples = zip(range(10), [-x for x in range(10)]) 
>>> listOfTuples 
[(0, 0), (1, -1), (2, -2), (3, -3), (4, -4), (5, -5), (6, -6), (7, -7), (8, -8), (9, -9)] 
>>> theDict = dict(listOfTuples) 
>>> theDict 
{0: 0, 1: -1, 2: -2, 3: -3, 4: -4, 5: -5, 6: -6, 7: -7, 8: -8, 9: -9} 
>>> 

Có một cú pháp Scala tương đương? Tôi thấy rằng bạn có thể sử dụng số lượng loại Tuple2 để biến đổi bản đồ, ví dụ:

scala> val theMap = Map((0,0),(1,-1)) 
theMap: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1)) 

scala> theMap(0) 
res4: Int = 0 

scala> theMap(1) 
res5: Int = -1 

scala> val tuplePairs = List((0,0),(1,-1)) 
tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) 

scala> val mapFromIterable = Map(tuplePairs) 
<console>:6: error: type mismatch; 
found : List[(Int, Int)] 
required: (?, ?) 
     val mapFromIterable = Map(tuplePairs) 
           ^

Tôi có thể lặp lại và chỉ định từng giá trị theo cách thủ công, nhưng có vẻ như phải có cách tốt hơn.

scala> var theMap:scala.collection.mutable.Map[Int,Int] = scala.collection.mutable.Map() 
theMap: scala.collection.mutable.Map[Int,Int] = Map() 

scala> tuplePairs.foreach(x => theMap(x._1) = x._2)          

scala> theMap 
res13: scala.collection.mutable.Map[Int,Int] = Map((1,-1), (0,0)) 

Trả lời

10

sử dụng Scala 2.8.0 chính thức, bạn có thể làm điều đó như thế này:


scala> val tuplePairs = List((0,0),(1,-1)) 
tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) 

scala> tuplePairs.toMap 
res0: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1)) 

Nếu bạn đang sử dụng Scala 2.7.7 bạn có thể làm một cái gì đó như thế này, như là một thay thế cho các phương pháp bạn đã sử dụng:


scala> val tuplePairs = List((0,0),(1,-1)) 
tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) 

scala> Map(tuplePairs: _*) 
res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1) 

nhưng như bạn có thể thấy, trong 2.8.0 mọi thứ đã được cải thiện nhiều.

+0

toMap hoạt động tốt. Rõ ràng hơn cú pháp ++. – I82Much

+3

Bản đồ 'trong câu trả lời 2,7 là không cần thiết. 'Map() ++ tuplePairs' sẽ làm, như' Bản đồ (tuplePairs: _ *) '. –

+0

Thật vậy, bạn tất nhiên, cảm ơn –

2

Có một số tùy chọn. Đầu tiên (nhưng không được đề xuất, IMO), bạn có thể chuyển đổi List thành một varargs bằng cách sử dụng list:_* Hoặc, bạn có thể sử dụng chức năng ++ để thêm danh sách giá trị vào bản đồ (đó là những gì Map.apply thực hiện)

scala> (Map[Int,Int]()) ++ List((1,2),(3,4)) 
res4: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4) 

scala> Map(List((1,2),(3,4)):_*) 
res5: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4) 
+0

Tại sao bản đồ của tôi in như Bản đồ ((1 -1,), (0, 0)) trong khi của bạn đi đến bản đồ đẹp hơn in (1 -> -1, 0 -> 0)? Bất kỳ ý tưởng? – I82Much

+0

Điều này hoạt động hoàn hảo. Cảm ơn. – I82Much

+0

Không có đầu mối, thực sự. Có ai biết không? Hmm, thiết bị đầu cuối này vẫn còn 2.7.7, đó là lý do tại sao? –

4

Trong khi có một số câu trả lời đưa ra lời khuyên tốt, đây là những gì tôi nghĩ là gần nhất với mã python gốc.

// Scala 2.8 
val listOfTuples = (0 until 10) zip (for (x <- 0 until 10) yield -x) 
val theMap = Map(listOfTuples:_*) 

Scala 2,7 không có zip lên hàng loạt, tuy nhiên, do đó bạn phải chuyển đổi các dãy để Lists trong việc chuyển nhượng đầu tiên:

// Scala 2.7 
val listOfTuples = (0 until 10).toList zip (for (x <- 0 until 10) yield -x).toList 
val theMap = Map(listOfTuples:_*) 
2

tôi không thể để lại một bình luận cho câu trả lời được chấp nhận (không đủ danh tiếng), nhưng giải pháp đề xuất cho Scala 2.7 quá phức tạp:

scala> Map() ++ (tuplePairs map (t => (t._1,t._2))) 
res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1) 

"Bản đồ" không làm gì cả, nó chuyển Tuple2 thành Tuple2. này là đủ:

scala> Map() ++ tuplePairs 
res3: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1) 

Trong mắt tôi nó sẽ là tốt hơn nên dùng Map.empty:

scala> Map.empty ++ tuplePairs 
res4: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1) 
+1

Cảm ơn bạn đã thông tin. Tôi không bao giờ có thể tìm thấy phương pháp ++ .. làm thế nào để bạn thậm chí tìm kiếm cho điều đó? – I82Much

+0

Sử dụng ++ không phải ý tưởng của tôi, tôi vừa xóa bản đồ không cần thiết. Thật không may là 2,7 scaladocs dường như đã được gỡ bỏ từ scala-lang.org, nhưng ++ của một Map [A, B] được mô tả ở đó. – bseibold

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