红宝石是否有类似Python的列表推导?(Does Ruby have something like

2019-07-30 05:59发布

Python有一个很好的功能:

print([j**2 for j in [2, 3, 4, 5]]) # => [4, 9, 16, 25]

在Ruby中这是更简单:

puts [2, 3, 4, 5].map{|j| j**2}

但如果它是关于嵌套循环的Python看起来更方便。

在Python中,我们可以这样做:

digits = [1, 2, 3]
chars = ['a', 'b', 'c']    
print([str(d)+ch for d in digits for ch in chars if d >= 2 if ch == 'a'])    
# => ['2a', '3a']

在Ruby中相对应的是:

digits = [1, 2, 3]
chars = ['a', 'b', 'c']
list = []
digits.each do |d|
    chars.each do |ch|
        list.push d.to_s << ch if d >= 2 && ch == 'a'
    end
end
puts list

红宝石是否有类似的东西吗?

Answer 1:

在Ruby中的常用方法是适当结合可枚举和阵列的方法来实现相同的:

digits.product(chars).select{ |d, ch| d >= 2 && ch == 'a' }.map(&:join)

这比列表理解不再仅仅4个左右的字符,只是作为表现(当然,恕我直言,但由于列表内涵是名单单子只是一种特殊的应用程序,人们可以说,它可能是能够充分地重建,使用Ruby的收集方法),而不需要任何特殊的语法。



Answer 2:

正如你所知道的Ruby有列表内涵没有语法糖,这样你就可以得到接近是通过富有想象力的方式使用块。 人们提出了不同的想法,看看lazylist和诠释社会学的方法,有条件的都支持嵌套的内涵:

require 'lazylist'
list { [x, y] }.where(:x => [1, 2], :y => [3, 4]) { x+y>4 }.to_a
#=> [[1, 4], [2, 3], [2, 4]]

require 'verstehen'
list { [x, y] }.for(:x).in { [1, 2] }.for(:y).in { [3, 4] }.if { x+y>4 }.comprehend
#=> [[1, 4], [2, 3], [2, 4]]

当然,这是不是你会打电话惯用的红宝石,所以它通常是使用更安全典型的product + select + map的方式。



Answer 3:

正如上面所建议的RBK, 在Ruby中列出的理解提供了不同的方式来做事有点像Ruby的列表理解整体转换。

他们没有明确说明嵌套循环,但至少他们中的一些可以很容易地嵌套。

例如,由Robert Gamble的接受的答案建议加入一个Array#领悟方法。

class Array
  def comprehend(&block)
    return self if block.nil?
    self.collect(&block).compact
  end
end

已经这样做了,你可以写你的代码为:

digits.comprehend{|d| chars.comprehend{|ch| d.to_s+ch if ch =='a'} if d>=2}

比较的Python代码:

[str(d)+ch for d in digits for ch in chars if d >= 2 if ch == 'a']

差异是相当小的:

  1. 在Ruby代码是有点长。 但是这主要只是“领悟”时阐明的事实; 你可以随时调用它的东西,如果你想要更短。
  2. 在Ruby代码把事情以不同的顺序,阵列来在开始,而不是在中间。 但是,如果你仔细想想,这也正是你所期望,并希望,因为“一切方法”的理念。
  3. 在Ruby代码需要嵌套内涵嵌套括号。 我想不出解决此不使事情变得更糟一个明显的方式(你不想叫“[海峡,数字] .comprehend2”或什么...)。

当然,这里的Python的真正实力,如果你决定要延迟计算列表中,您可以理解成一个生成器表达式只是去掉括号(或把它们变成括弧,根据上下文)转换。 但即使在那里,你可以创建一个Array#lazycomprehend什么的。



文章来源: Does Ruby have something like Python's list comprehensions?