【问题标题】:Conditionally merge list elements有条件地合并列表元素
【发布时间】:2013-06-12 21:42:32
【问题描述】:

我想根据某个表达式有条件地合并列表中彼此跟随的元素。 一个更好地解释我想做的例子:

来自:

val list = List("a1", "a2", "b1", "b2", "b3", "a3", "a4")

我想将所有以 b 开头的元素合并为一个元素,以获得如下结果列表:

List("a1", "a2", "b1-b2-b3", "a3", "a4")

在我的用例中,b 元素总是按顺序排列,但 b 元素的数量可以从没有元素到几十个元素不等。

我试过做类似的事情

list.foldLeft("")((s1, s2) => if (s1.matches("""b\d""") && s2.matches("""b\d""")) s1 + "-" + s2 else s1)

但这并没有给我带来任何有用的东西。

关于如何解决这个问题的任何建议?

【问题讨论】:

    标签: scala


    【解决方案1】:

    可以使用foldLeft 并查看列表中最近插入的元素来完成:

    list.foldLeft(List[String]()) {
      case (Nil, str) => str :: Nil
      case (head :: tail, str) =>
        if (head(0) == 'b' && str(0) == 'b') (s"$head-$str") :: tail
        else str :: head :: tail
    }.reverse 
    //> res0: List[String] = List(a1, a2, b1-b2-b3, a3, a4)
    

    模式匹配也可以重写(如果你觉得更清楚的话):

    list.foldLeft(List[String]()) {
      case (head :: tail, str) if (head(0) == 'b' && str(0) == 'b') =>
        (s"$head-$str") :: tail
      case (other, str) =>
        str :: other
    }.reverse    
    

    【讨论】:

      【解决方案2】:

      这应该可以工作

      def aggregateByPrefix(xs: Seq[String], prefix: String) = {
        val (xs1, xs2) = xs.span(x => !x.startsWith(prefix))
        val (withPrefix, withoutPrefix) = xs2.partition(_.startsWith(prefix))
        val aggregated = withPrefix.mkString("-")
        xs1 ++ Seq(aggregated) ++ withoutPrefix
      }
      

      用法:

      aggregateByPrefix(List("a1", "a2", "b1", "b2", "b3", "a3", "a4"), "b")
      => List(a1, a2, b1-b2-b3, a3, a4)
      

      【讨论】:

        猜你喜欢
        • 2017-08-02
        • 2012-09-07
        • 1970-01-01
        • 1970-01-01
        • 2014-01-26
        • 2016-02-08
        • 2016-04-11
        • 2015-02-10
        • 2017-12-15
        相关资源
        最近更新 更多