什么是Ruby相当于Python`itertools.chain`?

时间:2015-01-13 10:14:15

标签: ruby

Python的itertools模块提供了许多关于使用生成器处理可迭代/迭代器的好东西。什么是Ruby等价的Python itertools.chain

5 个答案:

答案 0 :(得分:3)

我不是Ruby程序员,但我认为应该这样做:

def chain(*iterables)
   for it in iterables
       if it.instance_of? String
           it.split("").each do |i|
               yield i
           end
       else
           for elem in it
               yield elem
           end
       end
   end
end

chain([1, 2, 3], [4, 5, 6, [7, 8, 9]], 'abc') do |x|
    print x
    puts
end

<强>输出:

1
2
3
4
5
6
[7, 8, 9]
a
b
c

如果您不想拼合字符串,那么使用Array#flatten可以缩短为:

def chain(*iterables)
    return iterables.flatten(1) # not an iterator though
end
print chain([1, 2, 3], [4, 5, 6, [7, 8, 9]], 'abc')
#[1, 2, 3, 4, 5, 6, [7, 8, 9], "abc"]

答案 1 :(得分:1)

Python迭代器的Ruby等价物是Enumerator。没有方法可以链接两个Enumerator,但可以很容易地编写一个:{/ p>

class Enumerator
  def chain(*others)
    self.class.new do |y|
      [clone, *others.map(&:clone)].each do |e|
        loop do y << e.next end
      end
    end
  end

  def +(other)
    chain(other)
  end
end

e1 = %w[one two].each
e2 = %w[three four].each
e3 = %w[five six].each

e = e1.chain(e2, e3)

e.map(&:upcase)
# => ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX']

答案 2 :(得分:0)

来自Python docs for itertools.chain

  

创建一个迭代器,返回第一个iterable中的元素,直到   它耗尽,然后进入下一个迭代,直到所有的   迭代用尽了。用于处理连续序列   单一序列。

首先,Python中的一个例子

from itertools import chain

# nested arrays
iterables = [
                ["one", "two"], 
                ["three", "four"], 
                ["five", "six", "6", ["eight", "nine", "ten"]]
            ]

list(chain(*iterables))

输出:

['one', 'two', 'three', 'four', 'five', 'six', '6', ['eight', 'nine', 'ten']]

我正在学习Ruby,所以我尝试使用Python文档中的代码示例来复制行为:

# taken from Python docs as a guide
def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element  # NOTE! `yield` in Python is not `yield` in Ruby. 
            # for simplicity's sake think of this `yield` as `return`

我的Ruby代码:

def chain(*iterables)
  items = []
  iterables.each do |it|
    it.each do |item|
      items << item
     end
  end
  items
end

nested_iterables = [%w[one two], %w[three four], %W[five six #{3 * 2}]]
nested_iterables[2].insert(-1, %w[eight nine ten])

puts chain(*nested_iterables)  

# and to enumerate
chain(*nested_iterables).each do |it|
  puts it
end

两个输出:

["one", "two", "three", "four", "five", "six", "6", ["eight", "nine", "ten"]]

答案 3 :(得分:0)

代码

def chain(*aaa)
  aaa.each { |aa| (aa.class == String ? aa.split(//) : aa).each { |a| yield a } }
end

实施例

chain([0, 1], (2..3), [[4, 5]], {6 => 7, 8 => 9}, 'abc') { |e| print e, ',' }

输出

0,1,2,3,[4, 5],[6, 7],[8, 9],a,b,c,

答案 4 :(得分:0)

因为Ruby 2.6 Enumerable具有chain方法。它不会将字符串分割成字符。

相关问题