想象一下,我有一个3级或更多级别的嵌套列表(或任何其他集合),例如
val items: Seq[Seq[Seq[Int]]] = Seq(Seq(Seq(1,2,3), Seq(4,5,6), Seq(4,5,6)), Seq(Seq(1,2,3), Seq(4,5,6), Seq(4,5,6)))
根据布尔规则遍历此集合并收集子节点的最简洁方法是什么。
如给出以下规则
(item) => item % 2 == 0
返回
Seq(2,4,6,4,6,2,4,6,4,6)
没有平铺/展平列表或使用可变集合!
答案 0 :(得分:3)
前一段时间,有人问了一个关于嵌套Option
的类似问题。我提供了一个通用的解决方案模式,它适用于任何monadic结构。
请确保您拥有嵌套的monadic类型......它不适用于Seq [Any]
我将扩展它以处理Seq
的
import scala.language.higherKinds
case class Flattener[W[_], WW, T](fn : WW => W[T])
implicit def seqRecFlattenFn[WW, T](
implicit f: Flattener[Seq, WW, T] = Flattener((ww: WW) => Seq(ww))
) = Flattener((ww: Seq[WW]) => ww.flatMap(f.fn))
def seqRecursiveFlatten[WW, T](www: Seq[WW])(
implicit f : Flattener[Seq, Seq[WW], T]
) = f.fn(www)
val nestedSeq1 = Seq(Seq(Seq(Seq(5, 10), Seq(20, 30))))
// nestedSeq1: Seq[Seq[Seq[Seq[Int]]]] = List(List(List(List(5, 10), List(20, 30))))
val flatSeq1 = seqRecursiveFlatten(nestedSeq1)
// flatSeq1: Seq[Int] = List(5, 10, 20, 30)
val nestedSeq2 = Seq(Seq(Seq(Seq(Seq(Seq(Seq(5, 10), Seq(20, 30)))))))
// nestedSeq2: Seq[Seq[Seq[Seq[Seq[Seq[Seq[Int]]]]]]] = List(List(List(List(List(List(List(5, 10), List(20, 30)))))))
val flatSeq2 = seqRecursiveFlatten(nestedSeq)
// flatSeq2: Seq[Int] = List(5, 10, 20, 30)
现在你有一个平坦的Seq,所以应用任何过滤或你想要的任何东西。
答案 1 :(得分:0)
如果您需要处理任意嵌套列表,那么您必须处理Seq [Any]:
def flatFilter(src: Seq[Any], pred: (Int => Boolean)): Seq[Int] = {
if (src.isEmpty)
Seq.empty
else src.head match {
case car: Seq[Any] =>
flatFilter(car, pred) ++ flatFilter(src.tail, pred)
case car: Int =>
if (pred(car))
car +: flatFilter(src.tail, pred)
else
flatFilter(src.tail, pred)
case _ => flatFilter(src.tail, pred)
}
}