次のような整数範囲の要素のコレクションがあります
case class Element(id: Int, from: Int, to: Int)
val elementColl: Traversable[Element]
そして私はそれらをに蓄積したい
case class ElementAcc(ids: List[Int], from: Int, to: Int)
次のアルゴリズムに従って:
Element
私から1つを取り、elementColl
それを使用ElementsAcc
して、Element
取られたものと同じfrom / toを持つ新しいものを作成します。elementColl
を探しElement
ますElementAcc
。ElementAcc
し、の整数範囲を拡張してElementAcc
、新しい範囲を含めます。Element
elementColl
まだ割り当てられていない残りの要素に対して上記のプロセスを繰り返します。ElementAcc
これにより、のコレクションが作成されElementAcc
ます。ただ再帰的にアキュムレータに要素を追加することが簡単に十分に思えますが、私はの縮小サイズを処理する方法がわからないelementColl
、私は同じことを追加しないようにElement
複数のElementAcc
さん
編集:範囲の拡張については不明確だったと思います。例でこれを明確にしましょう:
私のアキュムレータの範囲は現在1〜5です。6〜8の範囲の要素はアキュムレータの範囲と重複しないため、含まれません。4から7の範囲の要素はオーバーラップし、含まれ、結果のアキュムレータの範囲は1から7になります。
私はこのように行きます:
1)とを取りElementAcc
、Element
を返す関数を記述しますElementAcc
。関数は次のようになります。
def extend(acc: ElementAcc, e: Element): ElementAcc = {
if(acc.from <= e.from && e.from <= acc.to)
ElementAcc(e.id :: acc.ids, acc.from, math.max(acc.to, e.to))
else if (acc.from <= e.to && e.to <= acc.to)
ElementAcc(e.id :: acc.ids, math.min(acc.from, e.from), acc.to)
else acc
}
foldLeft
多くの場合、オブジェクトを蓄積するときに適したソリューションです。アキュムレータの初期値と、アキュムレータと要素を受け取り、アキュムレータを返す関数が必要です。次に、のすべての要素を蓄積しますtraversable
。
編集:
2)異なるリストに蓄積するには、aList[ElementAcc]
とElement
:を組み合わせる別の関数を作成する必要があります。
def overlap(acc: ElementAcc, e: Element): Boolean = {
(acc.from <= e.from && e.from <= acc.to) || (acc.from <= e.to && e.to <= acc.to)
}
def dispatch(accList: List[ElementAcc], e: Element): List[ElementAcc] = accList match {
case Nil => List(ElementAcc(List(e.id), e.from, e.to))
case acc :: tail =>
if (overlap(acc, e)) extend(acc, e) :: tail
else acc :: dispatch(tail, e)
}
3)そしてそれはfoldLeftで使用されます:
val a = Element(0, 0, 5)
val b = Element(1, 3, 8)
val c = Element(2, 20, 30)
val sorted = List(a, b, c).foldLeft(List[ElementAcc]())(dispatch)
sorted: List[ElementAcc] = List(ElementAcc(List(1, 0),0,8), ElementAcc(List(2),20,30))
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加