当前位置:  开发笔记 > 后端 > 正文

重复一段代码,直到块本身返回false?

如何解决《重复一段代码,直到块本身返回false?》经验,为你挑选了2个好方法。

我想要:

    将块传递给方法调用,然后

    将整个方法调用作为while循环的条件传递,

    即使我不需要在循环内部放置任何逻辑.

具体来说,我有一个数组,我希望#reject!某些元素来自相当复杂的逻辑.后续调用#reject!可能会删除先前传递中未删除的元素.当#reject!最终停止查找要拒绝的元素时,它将返回nil.此时,我希望循环停止并继续执行程序.

我以为我可以做以下事情:

while array.reject! do |element|
    ...
  end
end

我还没有尝试过它,但是这个构造抛出了vim的ruby语法高亮显示器用于循环(即,它认为第一个do用于while语句,并认为第二个end实际上是封装方法的结束).我也尝试将其重写为while附加到begin...end块的内联修饰符,

begin; end while array.reject! do |element|
  ...
end

但它仍然以同样的方式搞砸了突出显示.在任何情况下,感觉就像是滥用while循环.

我能想到的唯一方法就是将方法调用指定为proc:

proc = Proc.new do
         array.reject! do |element|
           ...
         end
       end

while proc.call do; end

虽然有效,但感觉很笨拙,尤其是尾随do; end.

有没有优雅的方法来实现这一目标?



1> Stefan..:

这不仅仅是vim,while array.reject! do |element|语法无效:

$ ruby -c -e 'while array.reject! do |element| end'
-e:1: syntax error, unexpected '|'
while array.reject! do |element| end
                        ^

您可以使用{ ... }而不是do ... end:

while array.reject! { |element|
    # ...
  }
end

loopbreak:

loop do
  break unless array.reject! do |element|
    # ...
  end
end

更明确一点:

loop do
  r = array.reject! do |element|
    # ...
  end
  break unless r
end



2> coreyward..:

Ruby允许您将条件移动到循环语句的末尾.这样可以很容易地将结果存储在循环内部并根据条件检查它:

begin
  any_rejected = arr.reject! { … }
end while any_rejected

这可以和做的一样end while arr.reject! { … },但是在这里发生的事情要清楚得多,特别是在复杂的情况下reject!.


这比在条件或使用proc中嵌套`reject!`更清晰,并且会提示更少的wtf时刻.
IIRC,Matz不鼓励使用`begin ... end while condition`
推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有