我試圖找出一種方法來根據元素之間的x距離將列表中的所有對象組合在一起。組列表元素的距離小於x
舉例來說,如果距離1
然後
List(2,3,1,6,10,7,11,12,14)
會給
List(List(1,2,3), List(6,7), List(10,11,12), List(14))
我只能拿出棘手的方法和循環,但我想必須有一個清晰的解決方案。
我試圖找出一種方法來根據元素之間的x距離將列表中的所有對象組合在一起。組列表元素的距離小於x
舉例來說,如果距離1
然後
List(2,3,1,6,10,7,11,12,14)
會給
List(List(1,2,3), List(6,7), List(10,11,12), List(14))
我只能拿出棘手的方法和循環,但我想必須有一個清晰的解決方案。
您可以嘗試對列表進行排序,然後使用foldLeft對其進行排序。基本上類似的東西
def sort = {
val l = List(2,3,1,6,10,7,11,12,14)
val dist = 1
l.sorted.foldLeft(List(List.empty[Int]))((list, n) => {
val last = list.head
last match {
case h::q if Math.abs(last.head-n) > dist=> List(n) :: list
case _ => (n :: last) :: list.tail
}
}
)
}
結果似乎不錯,但逆轉。如果需要,在需要的時候打電話給「反向」。代碼變得
val l = List(2,3,1,6,10,7,11,12,14)
val dist = 1
val res = l.sorted.foldLeft(List(List.empty[Int]))((list, n) => {
val last = list.head
last match {
case h::q if Math.abs(last.head-n) > dist=> List(n) :: (last.reverse :: list.tail)
case _ => (n :: last) :: list.tail
}
}
).reverse
最乾淨的答案將依賴於一個,可能應該被稱爲groupedWhile
其中一個條件是真的,就確實分裂法。如果你有這種方法的話,那也只是
def byDist(xs: List[Int], d: Int) = groupedWhile(xs.sorted)((l,r) => r - l <= d)
但是我們沒有groupedWhile
。
因此,讓一個:
def groupedWhile[A](xs: List[A])(p: (A,A) => Boolean): List[List[A]] = {
val yss = List.newBuilder[List[A]]
val ys = List.newBuilder[A]
(xs.take(1) ::: xs, xs).zipped.foreach{ (l,r) =>
if (!p(l,r)) {
yss += ys.result
ys.clear
}
ys += r
}
ys.result match {
case Nil =>
case zs => yss += zs
}
yss.result.dropWhile(_.isEmpty)
}
現在,你有通用功能,您可以輕鬆地獲得特定的一個。
這似乎是完美的,但子列表顛倒了。 「h :: q」語句的含義是什麼? – Marco 2014-10-01 16:24:22
爲什麼你需要Math.abs,如果它被分類? n將永遠比last.head更大? – 2014-10-01 16:57:11
@Paul:我覺得有些反射。 – Agemen 2014-10-01 21:32:48