0

不幸的是,我被迫发布尽可能少的代码片段,所以我会尽力清楚地解释问题,提前为冗长道歉。

问题陈述(设计):

我有一个抽象类 Predicate,它由两个子类 NumericPredicate 和 CategoricalPredicate 实现,它们配备了“谓词类型”和“比较值”:

NumericPredicate -> 类型为“<=”或“>”,比较值是 double 类型(但任何可比较的对象都可以) CategoricalPredicate -> 类型为“is-in”或“is-not-in”,并且比较值是一组字符串(但任何配备相等的无序类型都可以在这里工作)

此谓词构成规则的头部(谓词类型的有序序列),如果所有谓词都成立,则匹配。

在这种情况下,谓词可以是“冗余的”(例如,“value <= 2”比“value <= 3”更具体,因此可以安全地删除后者)并且可以删除以提高规则的可读性(其次也有性能提升,但这不是这里的重点)。

目标:

我现在正在为此类规则头实施“减少”阶段,并且正在寻找一种干净的方法来实现这一目标。在实践中,给定集合元素的部分排序(部分是因为无法比较不同种类的谓词),我的减少在于原始集合的谓词中的最小值(每个谓词类型一个)。

我的实际解决方案:

我为 Predicate 类配备了特征 Comparable(“with Comparable[Predicate]”),因此方法“compareTo”在 NumericPredicate 和 CategoricalPredicate 中实现:

接下来是 NumericPredicate 类的方法的实现:

override def compareTo(o: Predicate) = {

  if(this.getPredicateType != o.getPredicateType)
    throw new IllegalStateException("Predicates of different type cannot be compared: " +
    this.getPredicateType + " vs " + o.getPredicateType)

  val num: NumericPredicate = o.asInstanceOf[NumericPredicate]

  if(this.threshold == num.threshold)
    0
  else {
    if(isMinEq == (this.threshold < num.threshold)) -1 else 1
  }
}

现在,我想要的是通过将不同的谓词组织成可比较的子集合来实现,这些子集合是独立处理的,如下所示:

 def simplify(steps: Array[Predicate]): Array[Predicate] ={
    val groups =
      filters.map(p => (p.getPredicateType, s))
      .groupBy(_._1)

    groups.map(_._2.min).map(_._2).toArray   
}

问题:

  1. 有没有更惯用的方式来在 Scala 中实现部分排序(并且能够在无与伦比的种类中保持所有最小值)?编辑:我知道我正在尝试将部分排序“破解”为总排序(因为它应该是 Comparable),但我看不到如何通过更合适的特征 PartialOrdering 实现我想要的

  2. 假设我的设计选择没问题,当比较两个无法比较的对象时,返回 0 或抛出异常会更好吗?(我的印象是我在默默地压制一个错误,因为在这种情况下,比较两个无法比较的元素是错误的和毫无意义的)

4

0 回答 0