比较 Ruby 中的浮点数时如何筛选出 NaN?
How do I screen out NaNs when comparing floats in Ruby?
我正在使用 Rails 5 和 Ruby 2.4。如何确定变量是否为数字?我以为 is_a?(Numeric) 是要走的路,但显然不适合我。我有这个代码
puts "guesses arr: #{guesses_arr}"
guesses_arr.map!{|str| str.is_a?(Numeric) && str == guesses_arr.max ? str : 0}
死于
guesses arr: [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
ArgumentError: comparison of Float with NaN failed
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `max'
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `block (2 levels) in guess_headers_from_data_cols'
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `map!'
我无法在控制台中重现此内容,因为我似乎无法生成包含所有这些 "NaN" 值的数组。关键是,我如何确保在我的循环中不会比较那些?
您可以通过调用Float::NAN
获得NaN
:
[7] pry(main)> Float::NAN
=> NaN
[8] pry(main)> Float::NAN.nan?
=> true
如果您只想删除 NaN:
guesses_arr.reject! { |x| x.nan? }
例如:
[4] pry(main)> [1.0, Float::NAN].reject(&:nan?)
=> [1.0]
您可以在控制台中生成一个 NaN
值数组,如下所示:
[ 0.0 / 0.0 ] * 3
# => [NaN, NaN, NaN]
不完全清楚您的代码在做什么,但可能值得注意的是 max
抛出异常,而不是相等性测试。顺便说一句,如果您尝试将每个数组值与最大值进行比较 - 您可能希望 max
在 map
之外,以避免多次计算它。
在此处关于拒绝 NaN
s 的其他答案的基础上,您可以将它们放在一起得到类似的东西:
# set up dummy data - 2 values and 3 NaNs
guesses_arr = [ 0.0 / 0.0 ] * 3 + [ 2.0, 3.0 ]
puts "guesses arr: #{guesses_arr}"
# => [NaN, NaN, NaN, 2.0, 3.0]
# remove NaNs in place
guesses_arr.reject!(&:nan?)
maximum = guesses_arr.max
guesses_arr.map!{|str| str.is_a?(Numeric) && str == maximum ? str : 0}
# => [ 0, 3.0 ]
编辑:如果您在数组中混淆了整数,请先尝试将它们转换为浮点数:
# set up dummy data - including floats and integers
guesses_arr = [ 0.0 / 0.0 ] * 3 + [ 2.0, 3.0, 0 ]
guesses_arr.map!(&:to_f).reject!(&:nan?)
# => [ 2.0, 3.0, 0.0 ]
我们可以做几件事。回答具体问题。
arr = [1.0, Float::NAN, "1.0", "1"]
arr.map(&:to_f).reject(&:nan?)
将是关于删除 NaN
的简明示例
假设您正试图从不一致的数据中获取最大值,首先我们需要使用如下方法对其进行清理,该方法会将字符串或整数转换为浮点数,否则return nil
.
def to_number(maybe_a_number)
Float(maybe_a_number)
rescue ArgumentError
nil
end
假设我们有上面的方法
guesses_arr.map(&:to_number).max # or .min
也就是说,很难调试的原因是您有一个 .map!
导致 guesses_arr
在您移动时发生变化。 (通常我们避免使用标准库 bang 方法,因为它们的对象错误很难调试。
我正在使用 Rails 5 和 Ruby 2.4。如何确定变量是否为数字?我以为 is_a?(Numeric) 是要走的路,但显然不适合我。我有这个代码
puts "guesses arr: #{guesses_arr}"
guesses_arr.map!{|str| str.is_a?(Numeric) && str == guesses_arr.max ? str : 0}
死于
guesses arr: [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
ArgumentError: comparison of Float with NaN failed
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `max'
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `block (2 levels) in guess_headers_from_data_cols'
from /Users/davea/Documents/workspace/myproject/app/services/text_table_to_race_time_converter_service.rb:2121:in `map!'
我无法在控制台中重现此内容,因为我似乎无法生成包含所有这些 "NaN" 值的数组。关键是,我如何确保在我的循环中不会比较那些?
您可以通过调用Float::NAN
获得NaN
:
[7] pry(main)> Float::NAN
=> NaN
[8] pry(main)> Float::NAN.nan?
=> true
如果您只想删除 NaN:
guesses_arr.reject! { |x| x.nan? }
例如:
[4] pry(main)> [1.0, Float::NAN].reject(&:nan?)
=> [1.0]
您可以在控制台中生成一个 NaN
值数组,如下所示:
[ 0.0 / 0.0 ] * 3
# => [NaN, NaN, NaN]
不完全清楚您的代码在做什么,但可能值得注意的是 max
抛出异常,而不是相等性测试。顺便说一句,如果您尝试将每个数组值与最大值进行比较 - 您可能希望 max
在 map
之外,以避免多次计算它。
在此处关于拒绝 NaN
s 的其他答案的基础上,您可以将它们放在一起得到类似的东西:
# set up dummy data - 2 values and 3 NaNs
guesses_arr = [ 0.0 / 0.0 ] * 3 + [ 2.0, 3.0 ]
puts "guesses arr: #{guesses_arr}"
# => [NaN, NaN, NaN, 2.0, 3.0]
# remove NaNs in place
guesses_arr.reject!(&:nan?)
maximum = guesses_arr.max
guesses_arr.map!{|str| str.is_a?(Numeric) && str == maximum ? str : 0}
# => [ 0, 3.0 ]
编辑:如果您在数组中混淆了整数,请先尝试将它们转换为浮点数:
# set up dummy data - including floats and integers
guesses_arr = [ 0.0 / 0.0 ] * 3 + [ 2.0, 3.0, 0 ]
guesses_arr.map!(&:to_f).reject!(&:nan?)
# => [ 2.0, 3.0, 0.0 ]
我们可以做几件事。回答具体问题。
arr = [1.0, Float::NAN, "1.0", "1"]
arr.map(&:to_f).reject(&:nan?)
将是关于删除 NaN
假设您正试图从不一致的数据中获取最大值,首先我们需要使用如下方法对其进行清理,该方法会将字符串或整数转换为浮点数,否则return nil
.
def to_number(maybe_a_number)
Float(maybe_a_number)
rescue ArgumentError
nil
end
假设我们有上面的方法
guesses_arr.map(&:to_number).max # or .min
也就是说,很难调试的原因是您有一个 .map!
导致 guesses_arr
在您移动时发生变化。 (通常我们避免使用标准库 bang 方法,因为它们的对象错误很难调试。