【问题标题】:Map Iterator into map将迭代器映射到地图中
【发布时间】:2012-12-05 06:24:20
【问题描述】:

我有以下情况: 我收到了一个特定类型的迭代器,并想把它变成一个特定的地图。 我觉得可能有一种非常简单的方法可以做到这一点,但我似乎无法弄清楚:) 下面是一些让事情更容易理解的代码:(我将案例类缩短到最低限度)

case class Fu(title: String)
case class Bar(name: String)
case class Match(f: Fu, b: Bar)
case class Result(name: String, fus: List[Fu])

val input: Iterator[Match] = ...

我最后想要的是这样的:

val output: Iterator[Result]

这里是棘手的部分: 匹配是独一无二的,但自然而然,每个 Fu 可以匹配多个 Bar。 我基本上希望将所有具有相同 Bar 的火柴拆开,并将它们的 Fus 放入一个列表中。有点像 Map[Bar, List[Fu]],只是我有一个类型。 Result 类也可以使用 Bars 而不是名称 String,但我真的不需要其他 Bar 信息。但这无关紧要。 输出类型也不是那么重要,无论是 Iterator、Iterable、List 还是其他任何类型。只要映射工作正常。

起初,我认为 Iterable 上的 groupBy 会完全符合我的要求,但我要么不知道如何正确使用 groupBy,要么它是该工作的错误函数 :) 使用 map 似乎是一个好的开始,但是我该如何构建列表呢?我可以很容易地将每个 Match 变成一个 Result,但是我最终会得到许多具有相同名称的 Result 对象...

非常感谢,感谢您的帮助!

编辑:也许我应该明确指出这与匹配字符串无关。它们只是两个案例类的示例属性。所有 Fus 和 Bars 都已正确匹配到 Match 对象中。

【问题讨论】:

    标签: scala iterator


    【解决方案1】:

    您与groupBy 走在了正确的轨道上。下面是它的外观:

    val input: Iterator[Match] = Iterator(
      Match(Fu("A"), Bar("1")),
      Match(Fu("B"), Bar("2")),
      Match(Fu("C"), Bar("1")),
      Match(Fu("D"), Bar("2")))
    
    val output =
      input.toList
        .groupBy { case Match(f, Bar(name)) => name }
        .map { case (name, fus) => Result(name, fus.map(_.f)) }
    
     output foreach println                         //> Result(1,List(Fu(A), Fu(C)))
                                                    //| Result(2,List(Fu(B), Fu(D)))
    

    【讨论】:

    • 非常感谢!我想我根本没有意识到我需要将 groupBy 输出映射到正确的“表单”中。 .toList 导致惰性输入迭代器被完全加载,对吗?
    • 是的,.toList 会将迭代器加载到内存中,但是没有办法将所有内容都放在内存中,因为您需要查看整个迭代器以确保您获得了所有 Fus对于每个特定的Bar
    • 是的,有道理,只是想确认一下 :)
    猜你喜欢
    • 2019-08-15
    • 2021-04-15
    • 2011-07-31
    • 2012-04-27
    • 1970-01-01
    • 2011-04-02
    • 2023-03-31
    • 2014-02-19
    • 2017-04-20
    相关资源
    最近更新 更多