【问题标题】:Flatten a list of Anorm tuples展平异常元组列表
【发布时间】:2014-06-19 19:56:07
【问题描述】:

给定一个 scala 列表,例如:

List( ~(OuterObj,InnerObj1), ~(OuterObj, InnerObj2), ...) 

在所有 OuterObj 相同而 InnerObj 可能不同的情况下,我需要将其“分组”为一个包含 InnerObj 列表的 OuterObj 对象。

换句话说,OuterObj 有一个属性innerList 为空,但我需要将原始列表转换为单个 OuterObj,这样:

OuterObj.innerList = List(InnerObj1, InnerObj2, ....)

我尝试使用.groupBy(_._1),但这并没有正确地对对象进行分组,我不知道从那里去哪里。

如果上下文有帮助,原始列表是使用以下解析器模式进行一对多(1 个外部对象到多个内部对象)的异常连接查询的结果:

SQL(" joining outer on inner sql using a left join.. ").as(OuterObj.parse ~ InnerObj.parse *) // this is what creates the list of tuples

【问题讨论】:

    标签: scala anorm


    【解决方案1】:
    tuples                            // List[(A, B)]
        .groupBy(_._1)                // Map[A , List[(A, B)]
        .mapValues(_.map(_._2))       // Map[A, List[B]]
        .toList                       // List[(A, List[B])]
        .map{ case (parent, children) =>
            parent.copy(
                innerList = children
            )
        }                             // List[A]
    

    使用外部连接,您确实应该选择性地解析内部对象,否则您将丢失没有内部对象的行(除非这是所需的效果)。在这种情况下,你会这样做:

    SQL(...).as(OuterObj.parse ~ (InnerObj.parse ?) *) // List[(A, Option[B])]                    
        .groupBy(_._1)                // Map[A , List[(A, Option[B])]
        .mapValues(_.map(_._2))       // Map[A, List[Option[B]]]
        .toList                       // List[(A, List[Option[B]])]
        .map{ case (parent, children) =>
            parent.copy(
                innerList = children.flatten
            )
        }                             // List[A]
    

    【讨论】:

    • 我正在使用左外连接。我认为当内部对象不存在时,这会阻止我丢失行?你是对的,当它们没有相应的“内部”时,我不想丢失“外部”行
    • 对。查询将保留行,但如果没有看到内部对象(当内部解析器不是可选的),解析器将不会。
    • 这一直有效,直到 mapValues 调用:它返回一个 Map[A, List[A]]。它似乎正在消除 B(内部对象)
    • 啊我通过将地图更改为:.map(._2) 而不是 .map(._1) 来修复它
    • 哎呀。对于那个很抱歉。错字。
    猜你喜欢
    • 2019-07-22
    • 2014-05-03
    • 2016-09-06
    • 1970-01-01
    • 2015-02-11
    • 2013-11-06
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多