2

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

从:

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)

但它并没有给我任何有用的东西。

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

4

2 回答 2

3

可以通过 afoldLeft并查看列表中最近插入的元素来完成:

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    
于 2013-06-12T13:29:03.503 回答
0

这应该工作

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)
于 2013-06-12T13:29:15.937 回答