我是红宝石的初学者,试图用它来帮助我分析生物数据。我需要尝试将一组数据(数组中的数字)与具有特定特征的另一个数据匹配(例如数字+/- 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.0646 171.0686 174.0644 174.0795 180.0539 182.1059
我需要将它与理论集相匹配,我需要生成容差为0.002我正在逐步编写代码以生成我的理论集,因为我还不熟悉编码,并且只是想知道如何在我的理论集合周围创建一个+/- 0.002的范围,以使其与实际匹配。
答案 0 :(得分:9)
ruby的范围是否以Float开头?
是的,您可以使用浮点数创建范围:
r = 0.25..0.75
#=> 0.25..0.75
但是您无法使用Range#each
来遍历它,因为each
依赖succ
(例如Integer#succ
)而Float
没有&#39} ; t实现该方法。
相反,您可以使用Range#step
并使用explcit增量值:
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]
答案 1 :(得分:1)
如果我已正确理解您的问题,您可以这样做:
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
。
答案 2 :(得分:1)
首先,这段代码:
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
答案 3 :(得分:-1)
您没有为范围方法显示结束end
- 显示的end
会关闭arr.each
循环。
这可能是问题吗?