Предположим, что у меня есть этот диапазон:
("aaaaa".."zzzzz")
Как я получил бы Энный объект от диапазона, не генерируя всю вещь перед ручным/каждым временем?
Перечислить только до n,
или
Разработайте функцию, которая с заданным числом n, f (n) дает вам n-й элемент Ваш диапазон возможных решений.
В вашем случае вы можете рассматривать свой диапазон как систему счисления с основанием 26. Восстановление числа - хорошо известная проблема. На моем сайте есть пример для перехода от числа с основанием 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"
Быстрый и простой способ:
("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+, в противном случае обновите или потребуйте "backports"