[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
例如,在上文中,为什么需要在|i|
之前放置i < 4
?
我是Ruby编程的新手,这个元素的目的让我感到厌烦。
答案 0 :(得分:4)
这是块的非常基本的Ruby语法。块有时可以获取条|
之间给出的参数。在你的情况下:
[1,2,3,4,5,6,7].delete_if { |i| i < 4 }
类型delete_if
的{{1}}方法接受块作为参数。给出bock时,块接受数组元素作为参数。因此,在这种情况下,它会对数组中的每个值进行迭代Array
。更具体地说,如果该元素是i
,则将从数组中删除该元素。结果将是:
< 4
您经常会看到Ruby类型方法的文档,例如:
[4,5,6,7]
这意味着该方法接受带参数的块,delete_if { |item| block } -> Array
是使用参数的一些代码,输出是另一个数组。该方法的描述解释了文档中的更多细节(例如,Ruby Array)。
我建议在线阅读一些Ruby入门信息或一本很好的介绍性书籍,这将更详细地解释这一点。
答案 1 :(得分:3)
你必须将i
放在那里,原因与你在{1}}放在第一行的原因相同:
i
您必须命名方法参数,稍后将其用作方法中的局部变量。
Ruby块类似于方法,它们也可以接收参数,声明它们的语法略有不同:将它们包含在def plus_one(i)
return i + 1
end
中。
答案 2 :(得分:1)
我已经重新回答了我的回答,即使OP的问题已经得到解答,因为我想到了一种解释这个问题的新方法,这可能有助于未来的SO用户提出同样的问题。
从高中代数中,你应该记住这样的函数:f(x) = x + 1
。
想象一下,在x + 1
:f(x) = { x + 1 }
然后将(x)
移到花括号内: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
你可以通过像这样定义一个lambda来提前定义greater_than_four
方法:
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 }
答案 3 :(得分:0)
您传递给delete_if
方法的参数是一个块以及传递给块的参数内的东西。
将块视为一种排序方法。 delete_if
方法遍历块并将当前项作为参数i
传递给块。如果条件的计算结果为true,那么该元素将被删除。