簡體   English   中英

Scala:如何從Set [K]和從K到V的函數創建Map [K,V]?

[英]Scala: How to create a Map[K,V] from a Set[K] and a function from K to V?

Set[K]創建Map[K,V] Set[K]並從KV函數的最佳方法是什么?

例如,假設我有

scala> val s = Set(2, 3, 5)
s: scala.collection.immutable.Set[Int] = Set(2, 3, 5)

scala> def func(i: Int) = "" + i + i
func: (i: Int)java.lang.String

創建Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55")的最簡單方法是什么Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55")

你可以使用foldLeft

val func2 = (r: Map[Int,String], i: Int) => r + (i -> func(i))
s.foldLeft(Map.empty[Int,String])(func2)

這將比Jesper的解決方案表現更好,因為foldLeft在一次傳遞中構造Map Jesper的代碼首先創建一個中間數據結構,然后需要將其轉換為最終的Map

更新:我寫了一個微基准測試每個答案的速度:

Jesper (original): 35s 738ms
Jesper (improved): 11s 618ms
           dbyrne: 11s 906ms
         Rex Kerr: 12s 206ms
          Eastsun: 11s 988ms

看起來它們幾乎都是一樣的,只要你避免構建一個中間數據結構。

那這個呢:

(s map { i => i -> func(i) }).toMap

這會將s的元素映射到元組(i, func(i)) ,然后將生成的集合轉換為Map

注意: i -> func(i)(i, func(i))

dbyrne建議首先創建一個集合的視圖(請參閱他的答案和評論),這樣可以防止創建中間集合,從而提高性能:

(s.view map { i => i -> func(i) }).toMap
scala> import collection.breakOut
import collection.breakOut

scala> val set = Set(2,3,5)
set: scala.collection.immutable.Set[Int] = Set(2, 3, 5)

scala> def func(i: Int) = ""+i+i
func: (i: Int)java.lang.String

scala> val map: Map[Int,String] = set.map(i => i -> func(i))(breakOut)
map: Map[Int,String] = Map(2 -> 22, 3 -> 33, 5 -> 55)

scala>

除了現有的答案,

Map() ++ set.view.map(i => i -> f(i))

非常簡短,表現更快(折疊/ breakOut)。

(注意視圖以防止創建新集合;它會在重新映射時執行。)

與所有優秀的語言一樣,有一百萬種方法可以做任何事情。

這是一個用自己拉動集合的策略。

val s = Set(1,2,3,4,5)
Map(s.zip(s.map(_.toString)).toArray : _*)

編輯:(_。toString)可以替換為返回V類型的函數

其他解決方案缺乏創造力。 這是我自己的版本,雖然我真的想擺脫_.head地圖。

s groupBy identity mapValues (_.head) mapValues func

沒有使用“字符串重復”運算符*定義func(i:Int):

scala> s map { x => x -> x.toString*2 } toMap
res2: scala.collection.immutable.Map[Int,String] = Map(2 -> 22, 3 -> 33, 5 -> 55)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM