跳过Enumerable#collect中的迭代
(1..4).collect do |x| next if x == 3 x + 1 end # => [2, 3, nil, 5] # desired => [2, 3, 5]
如果下next
条件满足, collect
放在数组中的nil
,而我想要做的是没有元素在返回的数组,如果条件满足。 这可能没有调用delete_if { |x| x == nil }
delete_if { |x| x == nil }
在返回的数组?
(使用Ruby 1.8.7;我的代码摘要很抽象)
有方法Enumerable#reject
服务的目的:
(1..4).reject{|x| x == 3}.collect{|x| x + 1}
直接使用一个方法的输出作为另一个方法的input的做法称为方法链接 ,在Ruby中非常常见。
顺便说一句, map
(或collect
)用于input枚举到输出的直接映射。 如果你需要输出不同数量的元素,那么你可能需要另一种Enumerable
方法。
编辑:如果您对某些元素迭代了两次这一事实感到困扰,那么可以使用基于inject
(或其类似方法,名为each_with_object
)的较不优雅的解决scheme:
(1..4).each_with_object([]){|x,a| a << x + 1 unless x == 3}
我只是简单地调用结果数组上的.compact
,它将删除数组中的所有nil实例。 如果你想修改现有的数组(没有理由不),可以使用.compact!
:
(1..4).collect do |x| next if x == 3 x end.compact!
只是一个build议,你为什么不这样做:
result = [] (1..4).each do |x| next if x == 3 result << x end result # => [1, 2, 4]
这样你保存了另一个迭代来从数组中删除nil元素。 希望它有助于=)
我会build议使用:
(1..4).to_a.delete_if {|x| x == 3}
而不是collect + next语句。
您可以将决策制定为辅助方法,并通过Enumerable#reduce
使用它:
def potentially_keep(list, i) if i === 3 list else list.push i end end # => :potentially_keep (1..4).reduce([]) { |memo, i| potentially_keep(memo, i) } # => [1, 2, 4]