Ruby 从大范围内获取第 n 项

发布于 2024-08-31 00:49:09 字数 103 浏览 10 评论 0原文

假设我有这个范围:

("aaaaa".."zzzzz")

如何从该范围中获取第 N 个项目,而不需要事先/每次生成整个项目?

Suppose I have this range:

("aaaaa".."zzzzz")

How would I get the Nth item from the range without generating the entire thing before hand/each time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

思念绕指尖 2024-09-07 00:49:09

一种快速简单的方法:

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

注意:我假设您想要一个适用于任何可枚举的解决方案,不适用于字母范围(在这种情况下,您应该直接计算它)。我还假设 Ruby 1.8.7+,否则升级或需要“向后移植”

A quick and easy way:

("aaaaa".."zzzzz").first(42).last  # ==> "aaabp"

If for some reason you have to do this over and over, or if you need to avoid building the intermediate array for the first N elements, you could write something like:

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"

Note: I'm assuming you want a solution that works for any Enumerable, not for range of letters (in which case you should calculate it directly). I'm also assuming Ruby 1.8.7+, otherwise upgrade or require "backports"

眼趣 2024-09-07 00:49:09

仅枚举最多 n,

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

在您的情况下,您可以将范围视为以 26 为基数的数字系统。重新确定数字的基数是一个众所周知的问题。 我的网站上有一个示例,用于从 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"

Enumerate only up to n,

or

Develop a function that given a number n, f(n) gives you the nth item of your range of possible solutions.

In your case you may treat your range as a number system with base 26. Rebasing a number is a well known problem. There's an example on my site to go from a base-10 number to a base-26 number (represented by the alphabet) even in ruby (made by a colleague of mine). Some variation of this algorithm would probably also work for you.

Update
Maybe it didn't sink in that this is your answer :D

Here's the ruby code to get the nth item of your range:

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

then you can use it like that.

irb(main):030:0> rbase(789).rjust(10,'a')
=> "aaaaaaabej"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文