简体   繁体   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?

What is the best way to create a Map[K,V] from a Set[K] and function from K to V ? Set[K]创建Map[K,V] Set[K]并从KV函数的最佳方法是什么?

For example, suppose I have 例如,假设我有

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

and

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

What is the easiest way of creating a Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55") 创建Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55")的最简单方法是什么Map[Int, String](2 -> "22", 3 -> "33", 5 -> "55")

You can use foldLeft : 你可以使用foldLeft

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

This will perform better than Jesper's solution, because foldLeft constructs the Map in one pass. 这将比Jesper的解决方案表现更好,因为foldLeft在一次传递中构造Map Jesper's code creates an intermediate data structure first, which then needs to be converted to the final Map . Jesper的代码首先创建一个中间数据结构,然后需要将其转换为最终的Map

Update: I wrote a micro benchmark testing the speed of each of the answers: 更新:我写了一个微基准测试每个答案的速度:

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

Looks like they are all pretty much the same as long as you avoid constructing an intermediate data structure. 看起来它们几乎都是一样的,只要你避免构建一个中间数据结构。

What about this: 那这个呢:

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

This maps the elements of s to tuples (i, func(i)) and then converts the resulting collection to a Map . 这会将s的元素映射到元组(i, func(i)) ,然后将生成的集合转换为Map

Note: i -> func(i) is the same as (i, func(i)) . 注意: i -> func(i)(i, func(i))

dbyrne suggests creating a view of the set first (see his answer and comments), which prevents an intermediate collection from being made, improving performance: 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>

In addition to the existing answers, 除了现有的答案,

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

is pretty short and performs as well as the faster answers (fold/breakOut). 非常简短,表现更快(折叠/ breakOut)。

(Note the view to prevent creation of a new collection; it does the remapping as it goes.) (注意视图以防止创建新集合;它会在重新映射时执行。)

As with all great languages, there's a million ways to do everything. 与所有优秀的语言一样,有一百万种方法可以做任何事情。

Here's a strategy that zips the set with itself. 这是一个用自己拉动集合的策略。

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

EDIT: (_.toString) could be replaced with some function that returns something of type V 编辑:(_。toString)可以替换为返回V类型的函数

The other solutions lack creativity. 其他解决方案缺乏创造力。 Here's my own version, though I'd really like to get rid of the _.head map. 这是我自己的版本,虽然我真的想摆脱_.head地图。

s groupBy identity mapValues (_.head) mapValues func

Without definition of func(i: Int) using "string repeating" operator *: 没有使用“字符串重复”运算符*定义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.

相关问题 如何使用Map([K,V])而不是Map [K,V]创建Map构造函数? - How to create a Map constructor using Map([K,V]) instead of Map[K,V]? 如何通过解析 CSV 文件来创建 Map[K, V] 和 Seq[A]? - How to create Map[K, V] and Seq[A] by parsing CSV file? Apache Spark-Scala-如何将FlatMap(k,{v1,v2,v3,...})转换为((k,v1),(k,v2),(k,v3),...) - Apache Spark - Scala - how to FlatMap (k, {v1,v2,v3,…}) to ((k,v1),(k,v2),(k,v3),…) 如何使用 Circe 对 Map[K,V] 进行编码 - How to Encode Map[K,V] using Circe 将Map [K,Option [V]]转换为Map [K,V]的更好方法 - Better way of converting a Map[K, Option[V]] to a Map[K,V] 可尝试[尝试[(K,V)]]尝试[Map [K,V]] - Iterable[Try[(K, V)]] to Try[Map[K, V]] 将RDD [(K,V)转换为Map [K,List [V]] - Convert RDD[(K,V) to Map[K,List[V]] 为将集合元素添加到Map [K,Set [V]]的创建状态转换的更好方法 - Better way to create state transformation for adding set elements to Map[K, Set[V]] Apache Spark-Scala-HashMap(k,HashMap [String,Double](v1,v2,..))到((k,v1),(k,v2),...) - Apache Spark - Scala - HashMap (k, HashMap[String, Double](v1, v2,..)) to ((k,v1),(k,v2),…) 如何使用scala.Float将Scala Map转换为Java Map到java.Float k / v转换 - How can I convert Scala Map to Java Map with scala.Float to java.Float k/v conversion
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM