我想基于某个表达式在列表中有条件地合并元素之后的元素。 一个例子来更好地解释我想做的事情:
来自:
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)
但它并没有给我任何有用的东西。
有关如何处理此事的任何建议?
答案 0 :(得分:3)
可以使用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
答案 1 :(得分: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)