【问题标题】:Scala for-comprehension returning an ordered mapScala for-comprehension 返回有序映射
【发布时间】:2011-04-19 04:23:44
【问题描述】:

如何使用 for-comprehension 来返回可以分配给有序 Map 的内容?这是我拥有的代码的简化:

class Bar
class Foo(val name: String, val bar: Bar)
val myList: java.util.List[Foo] = ...
val result: ListMap[String, Bar] =
    for {
        foo <- myList
    } yield (foo.name, foo.bar)

我需要确保我的结果是一个有序的 Map,按照从 for-comprehension 返回元组的顺序。

通过上述,我得到了错误:

error: type mismatch;
found   : scala.collection.mutable.Buffer[(String,Bar)]
required: scala.collection.immutable.ListMap[String,Bar]
foo <- myList

这样编译:

class Bar
class Foo(val name: String, val bar: Bar)
val myList: java.util.List[Foo] = ...
val result: Predef.Map[String, Bar] =
    {
        for {
            foo <- myList
        } yield (foo.name, foo.bar)
    } toMap

但是我假设地图不会被排序,我需要一个明确的 toMap 调用。

我怎样才能做到这一点?

【问题讨论】:

    标签: scala scala-2.8 scala-collections


    【解决方案1】:

    collection.breakOut 在这种情况下是你的好朋友,

    val result: collection.immutable.ListMap[String, Bar] = 
      myList.map{ foo => (foo.name, foo.bar) }(collection.breakOut)
    

    如果重要的是用for-comprehension的表达方式,会按如下方式进行,

    val result: collection.immutable.ListMap[String, Bar] = {
      for { foo <- myList } yield (foo.name, foo.bar)
    }.map(identity)(collection.breakOut)
    

    Scala 2.8 breakOut 已经很好地解释了 collection.breakOut

    【讨论】:

    • 我尝试了使用和不使用 .map(identity) 并且似乎都可以正常编译。使用 .map(identity) 有区别吗?
    • 第一种情况会直接从myList生成ListMap,而后者会从myList生成一个seq,然后再从中生成ListMap。
    【解决方案2】:

    您可以通过使用 ListMap 类的伴生对象来实现,如下所示:

    class Bar
    class Foo(val name: String, val bar: Bar)
    val myList: java.util.List[Foo] = ...
    val result = ListMap((for(foo <- myList) yield (foo.name, foo.bar)):_*)
    

    【讨论】:

    • 你能解释一下附加的 :_* 是什么意思吗?
    • 我想你从来没有弄明白;这只是说“将这些东西插入到采用 vargs 的方法中”的特殊语法,即 public void foo(String ...)
    猜你喜欢
    • 1970-01-01
    • 2015-12-30
    • 2012-10-02
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多