我是非常新的ruby并且无法确定我是否正确使用了ruby语言。我想知道数字数组中的任何一个是否可以被另一个数字整除。如果是这样,否则返回该数字,返回0。
def is_divisible(nums, n)
nums.each do |m|
if n % m == 0
return n
end
end
0
end
该功能正常工作但有一些方面,我认为这不是ruby的惯用语:
我应该检查nums
是否属于可以首先循环的类型或捕获异常(来自php和python我知道这些有不同的看法,但不能告诉ruby)
是否有更简洁的方法来构造循环和2个单独的返回值
此代码还有其他不正确之处吗?
答案 0 :(得分:2)
以下是我的想法:
命名:Ruby中的谓词方法名为predicate?
而不是is_predicate
,因此您的方法名称应为divisible?
...除了它 isn&#t; t 实际上是一个谓词。它不会测试一个数字是否可以被另一个数字整除,而是找到Enumerable
中可以被另一个数字整除的第一个数字。这句话几乎听起来像一个描述性的方法名称,不是吗?
def find_first_divisible(nums, n)
nums.each do |m|
if n % m == 0
return n
end
end
0
end
命名续:我们不会向您收取字符费用。如果你愿意的话,你可以使用更多的东西;-) nums
可能没问题,n
已经出现了,但是m
是什么?事实上,你有一个错误,这正是由于你混淆了n
和m
造成的。
def find_first_divisible(numbers, divisor)
numbers.each do |n|
if n % divisor == 0
return n
end
end
0
end
保护条款:对于这样的情况,您希望使用return
(或next
)提前爆发,我更喜欢使用保护条款样式表格"如果":
def find_first_divisible(numbers, divisor)
numbers.each do |n|
return n if n % divisor == 0
end
0
end
一行阻止:在这种情况下,块的内容足够短以适合一行,所以我会这样做。请注意,块格式有两种竞争样式:一种说明始终对多行块使用do
/ end
,并且始终对单行块使用{
/ }
。另一个说始终使用do
/ end
来主要用于副作用的块("命令块")和{
/ {{1}用于主要用于返回值的块("功能块")。我更喜欢后一种风格。
}
描述性方法:
def find_first_divisible(numbers, divisor)
numbers.each do |n| return n if n % divisor == 0 end
0
end
了解核心和标准库:这非常重要,您不想重新发明轮子!
def find_first_divisible(numbers, divisor)
numbers.each do |n| return n if (n % divisor).zero? end
0
end
注意我是如何改变块样式的:现在我们对返回值感兴趣,没有副作用。
使用有意义的名称提取方法:
def find_first_divisible(numbers, divisor)
numbers.find {|n| (n % divisor).zero? } || 0
end
现在,该方法将完全与问题中的说明完全相同:"在class Integer
def divisible_by?(n) (self % n).zero? end
end
def find_first_divisible(numbers, divisor)
numbers.find {|n| n.divisible_by?(divisor) } || 0
end
内,找到第一个numbers
n
divisible_by
,如果没有,则结果为divisor
"。
尊重约定:最后但同样重要的是,您应该尊重社区的惯例。搜索某些内容的方法应返回0
以指示缺少结果:
nil
答案 1 :(得分:1)
首先,您应该将这样的问题发布到CodeReview SE页面。现在回答你的问题:
红宝石通常不要这样做以允许鸭子打字。 Rubbyist假设程序员足够聪明,不会在字符串上调用is_divisible
方法。
Ruby带有扩展的Enumerable模块,我强烈建议您熟悉它:ruby-doc.org/core-2.0.0/Enumerable.html。例如,方法find
将完全满足您的需求:
def is_divisible(num, n)
num.find{|number| number % n == 0} || 0
end
你的代码似乎没问题,但是我会重新考虑它的名字 - 我希望它能返回真或假而不是第一个可分数。此外,当您使用简单条件执行一行时,请使用它:
return n if n % m == 0
您可以对do end
和{}
块使用类似的规则:
nums.each {|m| return n if n % m == 0 }
0
答案 2 :(得分:0)
Ruby核心Array
类包含许多有用的功能,在给定定义您感兴趣的内容的块时,以通用方式查询和/或重构数组。
带上你的书面说明:
我想知道数字数组中的任何一个是否可以被另一个数字整除。 如果是这样,否则返回该数字,返回0。
你可以这样做:
def is_divisible( nums, n )
nums.find { |x| x % n == 0 } || 0
end
使用内置的Array#find
方法。
然而,当你没有匹配时,返回0
通常不是惯用的Ruby。您如何区分包含0
的列表和默认值?所以通常我会像这样构造代码:
def find_first_divisible( nums, n )
nums.find { |x| x % n == 0 }
end
# If you really need default 0 for no match:
result = find_first_divisible( my_nums, divisor ) || 0
此方法也变得如此简单,理解.find
语句很容易(与查找自定义方法的定义相比),我可能不会在这里创建一个方法,除非它在多个地方被调用。这是个人选择。
对于检查类型,我倾向于在工厂方法和/或initialize
中进行防御,而不是在其他地方。这是一个更复杂的讨论 - 整本书可以写在打字系统,验证和测试方法,以及不同语言如何适应不同的方法。