此问题在此处已有答案:
How to sum array of numbers in Ruby?(16个答案)
八年前就关门了。
问:写一个方法,sum,它接受一个数字数组并返回这些数字的和。
答:
def sum(nums)
total = 0
i = 0
while i < nums.count
total += nums[i]
i += 1
end
# return total
total
end
一定有别的方法不用while来解决这个问题,对吧?有人知道怎么做吗?
编辑:这不是考试或测试。这是github上为app academy提供的一个练习题。他们提供了问题和答案作为例子。我只是读到优秀的程序员不喜欢使用while或unless,所以我很好奇我是否可以学习一些更好的方法来解决这个问题。比如使用enumerable?(显然,Ruby的Noob在这里...)
此外,我会喜欢任何演练或方法,我应该学习..这个问题也是不同的,因为我要求使用这些数据的具体例子。
2条答案
按热度按时间mqkwyuun1#
通常的做法是:
它是这样的缩写:
我看到Neil发布了一个类似的解决方案,我在这里只需要注意
reduce
和inject
是同一个方法的两个名称- Ruby有几个类似的别名,这样习惯于其他不同语言的人就可以找到他们想要的东西。当使用reduce
/inject
的具名方法时,这是选择性的,但在其他情况下则不是。解释如下。
在Ruby中,通常不使用显式循环(
for
,while
,等等).相反,您可以调用正在迭代的集合上的方法,并向它们传递一个 block 代码,以在每个项上执行. Ruby的语法将block放在方法的参数之后,在do
...end
或{
...}
之间,因此它看起来像传统的命令式流控制,但工作方式不同。基本迭代方法为
each
:这将调用块
do |i| puts i end
三次,传递1,然后传递2,最后传递3。|i|
是一个块参数,它告诉Ruby每次将传递到块中的值放在哪里。但是
each
只是丢弃了块调用的返回值(在本例中,是puts
返回的三个nil
)。如果你想对这些返回值做些什么,你必须调用一个不同的方法。例如,map
返回一个返回值数组:这在这里不是很有趣,但是如果块返回一些东西,它会变得更有用:
如果你想把结果 * 合并 * 成一个聚合返回值,而不是返回一个与输入大小相同的数组,这时你需要
reduce
。除了一个块,它还需要一个额外的参数,块本身也用一个额外的参数调用。与这个参数对应的额外参数称为“accumulator”;第一次调用该块时,它获取最初传递给reduce
的参数,但从那时起,它获取对该块的 previous 调用的返回值,这是每个块调用将信息沿着给下一个块的方式。这使得
reduce
比map
更通用;实际上,你可以通过传入一个空数组并将块添加到其中来从reduce
构建map
:但是由于
map
已经定义好了,所以通常只会用它来做这个,而且只会用reduce
来做一些更简化的事情:......这也是我们解决你问题的方法。
Neil和我采取了一些额外的捷径。首先,如果一个块只对它的参数调用一个方法并返回结果,那么你可以通过在方法名前加上前缀
&:
来得到一个等价的块。也就是说:可以更简单地改写为:
由于Ruby中的
a + b
实际上只是编写方法调用a.+(b)
的一种更熟悉的方式,这意味着您只需传入&:+
就可以将数字相加:接下来,
reduce
的初始累加器值是可选的;如果省略它,那么第一次调用该块时,它将获得数组的前 * 两 * 个元素。最后,当你传入一个不是文本代码块的块时,你通常需要
&
。你可以把块转换成Proc对象,并把它们存储在变量中,通常把它们当作任何其他值,包括把它们作为常规参数传递给方法调用。所以当你想在方法调用中使用一个块作为 block 时,您可以使用&
来指示。一些方法,包括
reduce
,也会接受一个空符号(比如:+
)并为你创建Proc/block; Neil利用了这一点。但是其他迭代器方法,比如map
,就不是这样工作的:所以我总是使用
&
。Ruby有很多很好的在线教程,关于map/reduce和相关概念的更多一般信息,以及如何将它们应用到解决问题中,你应该搜索“函数式编程”的介绍,之所以叫它,是因为它对待“函数”(也就是可执行代码块,在Ruby中实现为
Proc
对象)作为值,就像数字和字符串一样,可以传递,分配给变量等。b09cbbtk2#
在Ruby中,最常用的方法可能是:
......虽然这基本上隐藏了所有的工作,所以这取决于测试试图测试什么。
Array#inject的文档