假设我有这个范围:
("aaaaa".."zzzzz")
我怎样才能从范围中获得第N个项目,而不是事先产生整个事物/每次?
答案 0 :(得分:8)
快速简便的方法:
("aaaaa".."zzzzz").first(42).last # ==> "aaabp"
如果由于某种原因你必须反复这样做,或者如果你需要避免为前N个元素构建中间数组,你可以编写如下内容:
module Enumerable
def skip(n)
return to_enum :skip, n unless block_given?
each_with_index do |item, index|
yield item unless index < n
end
self
end
end
("aaaaa".."zzzzz").skip(41).first # ==> "aaabp"
注意:我假设你想要一个适用于任何Enumerable的解决方案,而不是字母范围(在这种情况下你应该直接计算)。我也假设Ruby 1.8.7+,否则升级或require "backports"
答案 1 :(得分:1)
仅枚举n,
或
开发一个给定数字n的函数,f(n)为您提供所有可能解决方案的第n项。
在您的情况下,您可以将您的范围视为具有基数26的数字系统。重新计算数字是一个众所周知的问题。即使在红宝石(由我的同事制作)中,也有example on my site从基数为10的数字到基数为26的数字(由字母表示)。此算法的某些变体可能也适合您。
<强>更新强> 也许这不是因为这是你的答案:D
以下是获取范围第n项的红宝石代码:
def rbase(value)
a = ('a'..'z')
b = a.to_a
base = b.length
text = []
begin
value, rest = value.divmod(base)
text << b[rest]
end until value.zero?
text.reverse.join
end
那么你就可以这样使用它。
irb(main):030:0> rbase(789).rjust(10,'a')
=> "aaaaaaabej"