LINUX.ORG.RU

Ruby, итераторы


0

1

Доброго дня всем. Переписываю кусок кода с питона на руби, и ищу элегантное решение, прошу помощи. Код генерирует всемозможные комбинации размером в три знака из чисел от 0 до 9.

from itertools import product
numbers = product("0123456789", repeat=3)
while 1:
    try:
        print ''.join(numbers.next())
    except StopIteration:
        break

На руби получается нечто вроде

for c1 in 0..9
  for c2 in 0..9
    for c3 in 0..9
      ..
end end end
Но решение уродливое, на мой взгляд. Потому что в трёх знаках выглядит проще и нагляднее вроде, но если взять от 8 знаков и выше - то выглядит код отвратно. Та же история с
(0..9).each do |c1|
(0..9).each do |c2|
...
Есть ли наиболее лаконичное что-то? Наподобие библиотеки itertools в питоне. Спасибо. :)

форматированный вывод целочисленного вообще уже не в моде?

for x in xrange(1000): print '%03i' % x

аналогично на ruby

mashina ★★★★★
()
Ответ на: комментарий от mashina

сорри, не упомянул...

вместо «0123456789» может быть «abcdef...», аналогично на руби 'a'..'z'.

Так что интересуют итераторы, но за пример все равно спасибо.

chinarulezzz ★★
() автор топика
Ответ на: комментарий от derlafff

делает, да не то ;) Вы не поняли, ваш пример не работает как нужно.

chinarulezzz ★★
() автор топика
Ответ на: комментарий от chinarulezzz

>>все равно не то, а будь вместо цифр символы? (((

понял

exception13 ★★★★★
()

Напиши класс product, который спрячет все уродство и будет красиво как в питоне. Или напиши на питоне без «from itertools import product» :-)

sdio ★★★★★
()
def product(xs, n, &block)
  return block.call([]) if n == 0
  xs.each do |x|
    product(xs, n - 1) {|ys| block.call([x] + ys) }
  end
end

product("123456".chars, 3) do |xs|
  p xs
end
tarc
()
Ответ на: Спасибо от chinarulezzz

Вот еще вариант. Попроще и без рекурсии :)

def product(range, n, &block)
        lots_of_fors, str, lots_of_ends = '', '', ''
        n.times do |i|
                lots_of_fors += "for i#{i} in range\n"
                str += '#{i' + i.to_s + '}'
                lots_of_ends += 'end '
        end
        eval("#{lots_of_fors} block.call(\"#{str}\") #{lots_of_ends}")
end
Apple-ch ★★
()
Ответ на: комментарий от tarc

Чувствуется рука хаскелиста или лиспера )))

2 ТС
google://ruby array cartesian product

cathode
()

Некрасиво обрабатывать StopIteration руками:

from itertools import product
numbers = product("0123456789", repeat=3)
for i in numbers:
    print ''.join(i)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.