Scala将集合转换为按键映射的最佳方法是什么?

180

如果我有一个类型为 T 的集合 c,并且在 T 上有一个属性 p(比如类型为 P),那么做一个 通过提取键进行映射 的最佳方法是什么?

val c: Collection[T]
val m: Map[P, T]

一种方法如下所述:

m = new HashMap[P, T]
c foreach { t => m add (t.getP, t) }

但现在我需要一个可变的映射。有没有更好的方法可以在一行内完成,并且最终得到一个不可变的映射?(显然,我可以将上述内容转化为简单的库实用程序,就像在Java中一样,但我怀疑在Scala中没有这个必要)

13个回答

1

说句实话,这里有两种毫无意义的做法:

scala> case class Foo(bar: Int)
defined class Foo

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> val c = Vector(Foo(9), Foo(11))
c: scala.collection.immutable.Vector[Foo] = Vector(Foo(9), Foo(11))

scala> c.map(((_: Foo).bar) &&& identity).toMap
res30: scala.collection.immutable.Map[Int,Foo] = Map(9 -> Foo(9), 11 -> Foo(11))

scala> c.map(((_: Foo).bar) >>= (Pair.apply[Int, Foo] _).curried).toMap
res31: scala.collection.immutable.Map[Int,Foo] = Map(9 -> Foo(9), 11 -> Foo(11))

此外,值得一提的是,在 Haskell 中这两个代码看起来是这样的:Map.fromList $ map (bar &&& id) cMap.fromList $ map (bar >>= (,)) c - missingfaktor

-2
这对我有效:
val personsMap = persons.foldLeft(scala.collection.mutable.Map[Int, PersonDTO]()) {
    (m, p) => m(p.id) = p; m
}

这个 Map 必须是可变的,并且必须返回该 Map,因为向可变的 Map 添加元素不会返回一个 Map。


1
实际上,它可以按照以下方式不可变地实现: (m, p) => m + (p.id -> p) }``` 如上所示,Map可以是不可变的,因为向不可变的Map添加条目会返回一个新的不可变的Map。该值在折叠操作中作为累加器。 - RamV13

-3
使用map()在集合上,然后跟着toMap()。
val map = list.map(e => (e, e.length)).toMap

4
这与7年前提交并被接受的答案有何不同? - jwvh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接