Я не думаю, что вы найдете удобную готовую реализацию этой коллекции, но вы можете сделать вашу более общую, используя scala.math.PartialOrdering
и тот факт, что наборычастично упорядочено отношением подмножеств.
Сначала для определения Picky
.По сути, вам нужен контейнер, содержащий только максимальные элементы , где элементы не упорядочены относительно друг друга, а все более мелкие элементы удалены.
class Picky[A: PartialOrdering] private(val xs: Seq[A]) {
def +(y: A): Picky[A] = new Picky(Picky.add(xs, y))
override def toString = "Picky(%s)".format(xs.mkString(", "))
}
object Picky {
def apply[A: PartialOrdering](xs: A*): Picky[A] =
new Picky(xs.foldLeft(Seq.empty[A])(add))
private def add[A](xs: Seq[A], y: A)(implicit ord: PartialOrdering[A]) = {
val notSmaller = xs.filterNot(ord.lteq(_, y))
if (notSmaller.exists(ord.lteq(y, _))) notSmaller else notSmaller :+ y
}
}
Далее длячастичное упорядочение наборов, которое определяется только в том случае, если один из наборов является подмножеством другого (возможно, тривиально):
implicit def subsetOrdering[A] = new PartialOrdering[Set[A]] {
def tryCompare(x: Set[A], y: Set[A]) =
if (x == y) Some(0)
else if (x subsetOf y) Some(-1)
else if (y subsetOf x) Some(1)
else None
def lteq(x: Set[A], y: Set[A]) =
this.tryCompare(x, y).map(_ <= 0).getOrElse(false)
}
Следующее эквивалентное определение tryCompare
может быть немного быстрее:
def tryCompare(x: Set[A], y: Set[A]) = {
val s = (x & y).size
if (s == x.size || s == y.size) Some(x.size - y.size) else None
}
Теперь мы получаем желаемые результаты:
scala> Picky(Set(1, 2)) + Set(1)
res0: Picky[scala.collection.immutable.Set[Int]] = Picky(Set(1, 2))
scala> Picky(Set(1)) + Set(1, 2)
res1: Picky[scala.collection.immutable.Set[Int]] = Picky(Set(1, 2))
scala> Picky(Set(1, 3)) + Set(1, 2)
res2: Picky[scala.collection.immutable.Set[Int]] = Picky(Set(1, 3), Set(1, 2))
scala> Picky(Set(1, 2), (Set(1)))
res3: Picky[scala.collection.immutable.Set[Int]] = Picky(Set(1, 2))
Обратите внимание, что мы могли бы очень легко определить альтернативный частичный порядок, который дал бы Picky
простой старый набор семантики (то есть, только равныйвсе упорядочено по отношению друг к другу, и они всегда равны).