我是红宝石的初学者,试图用它来帮助我分析生物数据。我需要尝试将一组数据(数组中的数字)与具有一定特异性(例如 number+/- 0.25)的另一组数据相匹配 我想出了这个(到目前为止)将一个数据集更改为范围,而不是数字:
def range(arr)
c = []
arr.each do |b|
b = (b-0.25..b+0.25)
b = b.to_a
c << b
end
c = c.flatten
return c
end
代码给出了所需的数组,但是我总是得到
TypeError: can't iterate from Float.
我该如何解决这个问题?
背景
这是我的实际数据示例:
119.0456 119.0714 119.0721 119.0737 120.0772 130.0746 131.0737 136.0721 140.0951 143.0697 154.038 154.0744 154.1108 155.0949 156.054 169.053 170.1422 171.0646171.0686 174.0644 174.0795 180.0539 182.1059
我需要将其与理论集匹配,我需要在公差为 0.002 的情况下生成我正在逐步处理代码以生成我的理论集,因为我仍然不熟悉编码,只是想知道如何围绕我的理论集创建一个 +/- 0.002 的范围以将其与实际集相匹配。
红宝石的范围可以从浮点数开始吗?
是的,您可以使用浮点数创建范围:
r = 0.25..0.75
#=> 0.25..0.75
但是你不能使用Range#each
来遍历它,因为each
依赖于succ
(例如Integer#succ
),Float
不实现该方法。
相反,您可以将Range#step
与 take 一个显式增量值一起使用:
r.step(0.1) { |f| puts f }
输出:
0.25
0.35
0.45
0.55
0.65
0.75
只是为了好玩,让我们看看如果我们使用Float#next_float
会发生什么:
class Float
alias succ next_float
end
r = 0.25..0.75
r.each { |f| puts f }
输出:
0.25
0.25000000000000006
0.2500000000000001
0.25000000000000017
0.2500000000000002
0.2500000000000003
0.25000000000000033
0.2500000000000004
0.25000000000000044
0.2500000000000005
0.25000000000000056
0.2500000000000006
...
代码给出了所需的数组,但是我总是得到
TypeError: can't iterate from Float.
我该如何解决这个问题
您可以改为构建一个范围数组:
def range(arr)
arr.map { |b| b-0.25..b+0.25 }
end
range [1, 2, 3]
#=> [0.75..1.25, 1.75..2.25, 2.75..3.25]
首先,这段代码:
def range(arr)
c = []
arr.each do |b|
b = (b-0.25..b+0.25)
c << b
end
return c
end
基本上采用一个数组并创建一个新数组,每个项目都根据规则进行修改。在 Ruby 中,您可以使用.map()
来实现该目的:
def range(arr)
arr.map { |b| (b-0.25..b+0.25) }
end
其次,正如其他人所说,浮点数范围确实存在,但你不能迭代浮点数的范围,因为 Ruby 无法知道你想要什么增量。范围 (1.0 .. 2.0) 在技术上包含无限数量的数字(例如 1.2324123 和 1.9232311),因此如果不说明每个步骤应该有多大,就无法迭代。您可以像这样执行此操作:
range.step(0.1) { |f| #do stuff with f }
但是,如果您的目标是比较数组,看看 [1,2,3] 是否适合范围 [0.75..1.25, 1.75..2.25, 2.75..3.25],则根本不需要迭代范围。您应该改用.cover?()
方法,以查看数字是否在某个范围内:
def in_range(arr, ranges)
return false unless arr.size == ranges.size
arr.zip(ranges).do { |a, r| return false unless r.cover? a }
return true
end
如果我正确理解了您的问题,您可以改为这样做:
arr1 = [1,2,3]
arr2 = [1.25, 1.85, 4.25]
s = 0.25
arr1.zip(arr2).select { |a, b| (a-b).abs <= s }
#=> [[1, 1.25], [2, 1.85]]
关键方法:Array#zip
、Array#select
和Float#abs
。
您不显示范围方法的结束end
- 显示的end
关闭arr.each
循环。
这可能是问题所在吗?