Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 为子类B排序数组[B]的优雅方法<;A、 当一个扩展指令[A]时?_Scala_Boilerplate - Fatal编程技术网

Scala 为子类B排序数组[B]的优雅方法<;A、 当一个扩展指令[A]时?

Scala 为子类B排序数组[B]的优雅方法<;A、 当一个扩展指令[A]时?,scala,boilerplate,Scala,Boilerplate,定义了一个扩展排序[a]的类a和一个a的子类B之后,我如何对一个B数组进行自动排序?Scala编译器抱怨它“无法找到参数order:Ordering[B]的隐式值”。下面是一个具体的REPL示例(Scala 2.8),其中a=Score和B=CommentedScore: class Score(val value: Double) extends Ordered[Score] { def compare(that: Score) = value.compare(that.value) }

定义了一个扩展排序[a]的类a和一个a的子类B之后,我如何对一个B数组进行自动排序?Scala编译器抱怨它“无法找到参数order:Ordering[B]的隐式值”。下面是一个具体的REPL示例(Scala 2.8),其中a=Score和B=CommentedScore:

class Score(val value: Double) extends Ordered[Score] {
  def compare(that: Score) = value.compare(that.value)
}
defined class Score

trait Comment { def comment: String }
defined trait Comment

class CommentedScore(value: Double, val comment: String) extends Score(value) with Comment
defined class CommentedScore

val s = new CommentedScore(10,"great")
s: CommentedScore = CommentedScore@842f23

val t = new CommentedScore(0,"mediocre")
t: CommentedScore = CommentedScore@dc2bbe

val commentedScores = Array(s,t)
commentedScores: Array[CommentedScore] = Array(CommentedScore@b3f01d, CommentedScore@4f3c89)

util.Sorting.quickSort(commentedScores)
error: could not find implicit value for parameter ord: Ordering[CommentedScore]
       util.Sorting.quickSort(commentedScores)
                             ^
如果我知道如何以一种优雅的方式对数组[A]=数组[Score]进行排序(即,免费排序数组[B]=数组[CommentedScore]),从而避免使用样板文件,我该如何解决这个问题

谢谢

这是有效的:

val scoreArray: Array[Score] = Array(s, t)
util.Sorting.quickSort(scoreArray)
或者如果您从
数组[CommentedScore]
开始:

val scoreArray: Array[Score] = commentedScores.map(identity)
util.Sorting.quickSort(scoreArray)
注意:您可以更简单地使用以下方法进行排序:

scoreArray.sorted

添加所需的隐式表达式:

implicit val csOrd: Ordering[CommentedScore] = Ordering.by(_.value)
您可以将其放在
CommentedScore
伴随对象中,以便在使用站点中没有样板文件


编辑:如果希望仅在继承树的顶部定义排序方法,则仍然必须为每个子类提供
排序
,但可以根据
得分
对象中的方法定义
排序
比较
方法。i、 e

object Score {
  implicit val ord: Ordering[Score] = Ordering.by(_.value)
}

object CommentedScore {
  implicit val csOrd = new Ordering[CommentedScore] { 
    def compare(x: CommentedScore, y: CommentedScore) = Score.ord.compare(x, y)
  }
}
如果您不想为每个子类重新定义,可以使用泛型方法生成
排序

object Score {
  implicit def ord[T <: Score]: Ordering[T] = Ordering.by(_.value)
}
对象分数{

隐式定义ord[T您可以使用scalaz中的
Order
,这是一种反变量,因此您不需要为每个子类定义它。下面是一个示例:

import scalaz._
import Scalaz._

class Score(val value: Double)
object Score {
  implicit val scoreOrd: Order[Score] = orderBy(_.value)
}
trait Comment { def comment: String }
class CommentedScore(value: Double, val comment: String) extends Score(value) with Comment {
  override def toString = s"cs($value, $comment)"
} 
def quickSort[E: Order](list: List[E]): List[E] = list match {
  case Nil => Nil
  case head :: tail =>
    val (less, more) = tail partition { e => implicitly[Order[E]].order(e, head) == LT }
    quickSort(less) ::: head :: quickSort(more) 
}
println(quickSort(List(
  new CommentedScore(10,"great"),
  new CommentedScore(5,"ok"),
  new CommentedScore(8,"nice"),
  new CommentedScore(0,"mediocre")
))) // List(cs(0.0, mediocre), cs(5.0, ok), cs(8.0, nice), cs(10.0, great))

谢谢。但我希望这取决于分数顺序:假设我以后重构分数顺序,按降序排序,而不是按升序排序。我希望CommentedScore继承这一变化。有什么想法吗?非常感谢你,Luigi。不幸的是,我是Scala的新手,不知道“使用委派”是什么意思。如果不太麻烦的话,你介意演示一下你在
Score
案例中的意思吗?@PerfectTiling delegation只意味着将参数传递给另一个进行实际工作的方法。已在上面进行了编辑。谢谢。实际上,我在数组上使用了我自己的自定义部分排序算法。我将util.Sorting.quickSort在这里代替它。最后,我必须确保我有一个数组[CommentedScore],所以我不想转换为Arra[Score],然后转换为数组[CommentedScore]。我一直认为排序应该是协变的。不过我还没有机会仔细考虑。