6

假设我有这个范围:

("aaaaa".."zzzzz")

我如何从范围中获得第 N 个项目而不在手/每次之前生成整个事物?

4

2 回答 2

9

一种快速简便的方法:

("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"

于 2010-04-28T19:27:51.953 回答
1

最多只枚举 n,

或者

开发一个给定数字 n 的函数,f(n) 为您提供可能解决方案范围中的第 n 项。

在您的情况下,您可以将您的范围视为以 26 为底的数字系统。重新设置数字是一个众所周知的问题。在我的网站上有一个例子,即使在 ruby​​ 中(由我的同事制作),也可以从 10 进制数变为 26 进制数(用字母表示)。该算法的某些变体可能也适用于您。

更新 也许这不是你的答案:D

这是获取范围中第 n 项的 ruby​​ 代码:

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"
于 2010-04-28T19:29:18.203 回答