我似乎无法以微不足道的方式使用枚举器。 也许它实际上比我意识到的更有限。
这是一个例子,我认为枚举器很方便,但无法实现它们:
设array = [0,1,2,“+”,4]。
我有兴趣创建以下Enumerator-behavior:
也许问题是我不能“删除”已经产生的东西?换句话说,我不能不屈服?我对这种行为很感兴趣,因为它能够在改变数组之后在任何给定位置倒回序列(这会扰乱迭代的顺序)。
答案 0 :(得分:0)
Enumerator没有previous
方法,它不允许您在迭代时跳过值,并且它没有删除元素的方法。
因此,我认为您无法使用您发布的确切工作流程执行所需操作,但我确信可以创建您可能偏离工作流程时所寻求的行为。
答案 1 :(得分:0)
摘要 - 此选项似乎符合您所表达的标准:
[0, 1, 2, "+", 4].inject([]) { |n,e| n << (e == "+" ? n.pop(2).reduce(:+) : e) }
# => [0, 3, 4]
以下是我的想法......
选项1:
使用each_with_index
,这样您就可以轻松识别以前的元素。
array.each_with_index do |element, index|
your_logic_here
end
选项2:
或者为了避免改变数组,你可以简单地构建一个像这样的新数组:
new_array = []
array.each do |element|
if element == "+"
ele_sum = new_array.pop(2)
new_array << (ele_sum.reduce :+)
else
new_array << element
end
end
如果你没有发现它令人困惑,你可以将if语句中的两行合并到:
new_array << new_array.pop(2).reduce(:+)
或者如果你对三元运算符没问题,可以将整个事情缩短为:
def some_function(array)
new_array = []
array.each { |element| new_array << (element == "+" ? new_array.pop(2).reduce(:+) : element) }
end
> array = [0, 1, 2, "+", 4]
> some_function(array)
# => [0, 3, 4]
在irb中工作和测试
...或者当然使用注入然后你可以全部内联:
array.inject([]) { |new_array, element| new_array << (element == "+" ? new_array.pop(2).reduce(:+) : element) }
[0, 1, 2, "+", 4].inject([]) { |n,e| n << (e == "+" ? n.pop(2).reduce(:+) : e) }
# => [0, 3, 4]
但我更喜欢扩展版本的可读性