[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
例如,在上面,为什么需要放在|i|
before i < 4
?
我是 Ruby 编程的新手,这个元素的目的让我无法理解。
这是块的非常基本的 Ruby 语法。块有时可以采用在条之间给出的参数|
。在你的情况下:
[1,2,3,4,5,6,7].delete_if { |i| i < 4 }
该delete_if
类型的方法Array
接受一个块作为参数。当给定块时,块接受数组元素作为参数。因此,i
在这种情况下,它会遍历数组中的每个值。更具体地说,如果该元素是 ,则将从数组中删除该元素< 4
。结果将是:
[4,5,6,7]
你会经常看到 Ruby 类型方法的文档,例如:
delete_if { |item| block } -> Array
这意味着该方法接受一个带有参数的块,block
即使用该参数的一些代码,而输出是另一个数组。该方法的描述在文档中解释了更多细节(例如,Ruby Array)。
我建议在线阅读一些 Ruby 入门信息或一本很好的入门书籍,它将更详细地解释这一点。
您必须将其放在i
那里,原因与您i
在此处放入第一行的原因相同:
def plus_one(i)
return i + 1
end
您必须命名您的方法参数,稍后将其用作方法中的局部变量。
Ruby 块类似于方法,它们也可以接收参数,并且声明它们的语法略有不同:将它们包含在| |
.
即使已经回答了 OP 的问题,我也重做了我的答案,因为我想到了一种新的方法来解释这一点,这可能会帮助未来的 SO 用户解决同样的问题。
从高中代数开始,你应该记住这样的函数:f(x) = x + 1
.
想象一下在 周围放置花括号x + 1
:f(x) = { x + 1 }
然后将(x)
to 移到花括号内:f = {(x) x + 1 }
然后去掉名字f
:{(x) x + 1 }
。这使它成为“匿名函数”,即“lambda”。
问题是:大括号可能包含任意语句,它们本身可能使用括号:(x + 1) * 4
。那么 Ruby 怎么知道(x)
应该是函数的参数,而不是要执行的表达式呢?必须使用其他一些语法。因此竖线:|x|
。(至少我认为这是思考过程)。
{|i| i > 4 }
就像 一样,只是它没有名称并且没有预先定义,因此f(i) = i > 4
参数必须定义在函数本身的“内部”,而不是附加到名称之外。
Array#delete_if
期望这样一个函数(当它像这样使用时称为“块”)并且知道如何处理它。它将数组的每个成员[1,2,3,4,5,6,7]
作为参数传递到块中,i
以查看该成员是否i > 4
为真。这相当于做这样的事情:
def greater_than_four(x)
x > 4
end
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if greater_than_four(el)
end
greater_than_four
您可以通过动态定义 lambda来避免提前定义方法,如下所示:
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if lambda{|i| i > 4}.call(el)
end
但是由于Array#delete_if
已经期望一个块,并且已经知道在每个元素上调用它,您可以为自己节省大量代码:
[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
您传递给该delete_if
方法的参数是一个块,而您传递给该块的参数内部的东西。
将块视为一种方法。该delete_if
方法遍历块并将当前项作为参数i
传递给块。如果条件评估为真,则该元素将被删除。