使用 Double.NaN 的自定义比较器对双打列表进行排序
Sort a list of Doubles with custom comparator for Double.NaN
我有以下列表
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
我正在尝试按如下方式使用它 sortWith :
scala> res0.sortWith((d1, d2)=> sortAscendingDouble(d1, d2))
res1: List[Double] = List(NaN, 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(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 进行比较总是 return false
。因此你的第三个条件是错误的,因为 d2 < d1
将是 false
但它必须是 true
。您可以通过在这些特殊情况下为您的函数使用固定的 return 值来修复它。
/** 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)
我有以下列表
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
我正在尝试按如下方式使用它 sortWith :
scala> res0.sortWith((d1, d2)=> sortAscendingDouble(d1, d2))
res1: List[Double] = List(NaN, 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(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 进行比较总是 return false
。因此你的第三个条件是错误的,因为 d2 < d1
将是 false
但它必须是 true
。您可以通过在这些特殊情况下为您的函数使用固定的 return 值来修复它。
/** 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)