Scala 使用Double.NaN的自定义比较器对Double列表进行排序

Scala 使用Double.NaN的自定义比较器对Double列表进行排序,scala,list,sorting,apache-spark,comparator,Scala,List,Sorting,Apache Spark,Comparator,我有以下清单 scala> List(Double.NaN, 0.0, 99.9, 34.2, 10.98, 7.0, 6.0, Double.NaN, 5.0, 2.0, 0.56, Double.NaN, 0.0, 10.0) res0: List[Double] = List(NaN, 0.0, 99.9, 34.2, 10.98, 7.0, 6.0, NaN, 5.0, 2.0, 0.56, NaN, 0.0, 10.0) 这是我的比较器函数: scala> def so

我有以下清单

scala>  List(Double.NaN, 0.0, 99.9, 34.2, 10.98, 7.0, 6.0, Double.NaN, 5.0, 2.0, 0.56, Double.NaN, 0.0, 10.0)
res0: List[Double] = List(NaN, 0.0, 99.9, 34.2, 10.98, 7.0, 6.0, NaN, 5.0, 2.0, 0.56, NaN, 0.0, 10.0)
这是我的比较器函数:

scala> def sortAscendingDouble(d1:Double, d2:Double) = {
     | if(d1.isNaN && !d2.isNaN)
     | d1 < d2
     | else if(!d1.isNaN && d2.isNaN)
     | d2 < d1
     | else d1< d2
     | }
sortAscendingDouble: (d1: Double, d2: Double)Boolean
我不明白为什么第一个NaN不在列表的末尾。

我对升序排序列表的预期输出是:

List(0.0, 0.0, 0.56, 2.0, 5.0, 6.0, 7.0, 10.0, 10.98, 34.2, 99.9, NaN, NaN, NaN)
List(99.9, 34.2, 10.98, 10.0, 7.0, 6.0, 5.0, 2.0, 0.56, 0.0, 0.0, NaN, NaN, NaN
我对降序排序列表的预期输出是:

List(0.0, 0.0, 0.56, 2.0, 5.0, 6.0, 7.0, 10.0, 10.98, 34.2, 99.9, NaN, NaN, NaN)
List(99.9, 34.2, 10.98, 10.0, 7.0, 6.0, 5.0, 2.0, 0.56, 0.0, 0.0, NaN, NaN, NaN
在升序排序和降序排序的情况下,我希望NAN在末尾


我知道sortWith使我们能够编写自己的比较器。有人能帮我解决这个问题吗?

问题是,将任何数字(包括NaN本身)与NaN进行比较总会返回
false
。因此,您的第三个条件是错误的,因为
d2
将是
false
,但它必须是
true
。您可以通过在这些特殊情况下使用函数的固定返回值来修复它

/** Compares two doubles and returns true if the first value is equals or less than the second */
def sortAscendingDouble(d1: Double, d2: Double): Boolean =
  if (d1.isNaN && d2.isNaN)
    false // doesn't matter if true or false.
  else if(d1.isNaN && !d2.isNaN)
    false // NaN always goes after any non-NaN double.
  else if(!d1.isNaN && d2.isNaN)
    true // NaN always goes after any non-NaN double.
  else
    d1 < d2 // Standard double comparison. This should take care of any repetitive Doubles

/** Compares two doubles and returns true if the first value is equals or greater than the second */
def sortDescendingDouble(d1: Double, d2: Double): Boolean =
  if (d1.isNaN && d2.isNaN)
    false // doesn't matter if true or false.
  else if(d1.isNaN && !d2.isNaN)
    false // NaN always goes after any non-NaN double.
  else if(!d1.isNaN && d2.isNaN)
    true // NaN always goes after any non-NaN double.
  else
    d1 > d2 // Standard double comparison. This should take care of any repetitive Doubles

list.sortWith(sortAscendingDouble)
// List[Double] = List(0.0, 0.0, 0.56, 2.0, 5.0, 6.0, 7.0, 10.0, 10.98, 34.2, 99.9, NaN, NaN, NaN)

list.sortWith(sortDescendingDouble)
// List[Double] = List(99.9, 34.2, 10.98, 10.0, 7.0, 6.0, 5.0, 2.0, 0.56, 0.0, 0.0, NaN, NaN, NaN)
/**比较两个double,如果第一个值等于或小于第二个值,则返回true*/
def sortAscendingDouble(d1:Double,d2:Double):布尔值=
如果(d1.isNaN和d2.isNaN)
false//不管是真是假。
else if(d1.isNaN&&!d2.isNaN)
false//NaN总是跟在任何非NaN双精度后面。
else if(!d1.isNaN&&d2.isNaN)
true//NaN总是追求任何非NaN双精度。
其他的
d1d2//标准双重比较。这应该考虑到任何重复的双打
list.sortWith(sortAscendingDouble)
//列表[双]=列表(0.0,0.0,0.56,2.0,5.0,6.0,7.0,10.0,10.98,34.2,99.9,NaN,NaN,NaN)
list.sortWith(sortDescendingDouble)
//列表[双]=列表(99.9,34.2,10.98,10.0,7.0,6.0,5.0,2.0,0.56,0.0,0.0,0.0,NaN,NaN,NaN)

非常感谢您不需要这么多测试:
if(d1.isNaN)false else if(d2.isNaN)true else d1