Sum array of numbers
Q:写一个方法,求和,它取一个数字数组,并返回数字的和。
答:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def sum(nums) total = 0 i = 0 while i < nums.count total += nums[i] i += 1 end # return total total end |
必须有另一种不使用while的方法来解决这个问题,对吗?有人知道怎么做吗?
编辑:这不是考试。这是Github为应用学院提供的实践问题。他们以问题和答案为例。不过,我刚刚读到,优秀的程序员不喜欢使用while或until,所以我很好奇是否可以学习一些更好的方法来解决这个问题。像是可枚举的?(显然,这里没有红宝石…)
另外,我也很喜欢任何我应该学习的演练或方法。这个问题也是不同的,因为我在询问使用这些数据的具体示例。
通常的做法是:好的。
1 | def sum(nums) nums.reduce(&:+) end |
它的缩写是:好的。
1 | def sum(nums) nums.reduce(0) { |total, num| total + num } end |
号
我看到Neil在我打字的时候发布了一个类似的解决方案,所以我要注意的是,
解释如下。好的。
在Ruby中,通常不使用显式循环(
基本迭代法为
1 | [1,2,3].each do |i| puts i end |
这三次调用块
但是
1 2 | [1,2,3].map do |i| puts i end #=> [nil, nil, nil] |
。
这在这里不是很有趣,但是如果块返回某些内容,它会变得更有用:好的。
1 2 | [1,2,3].map do |i| 2*i end #=> [2,4,6] |
如果您希望将结果组合成单个聚合返回值,而不是返回与输入大小相同的数组,这时您需要到达
这使得
1 2 | [1,2,3].reduce([]) do |a,i| a + [2*i] end #=> [2,4,6] |
。
但是,由于
1 2 | [1,2,3].reduce(0) do |s, i| s + 2*i end #=> 12 |
。
…这就是我们为解决你的问题所做的。好的。
尼尔和我多走了几条捷径。首先,如果一个块只对其参数调用一个方法并返回结果,那么您可以通过在方法名前面加上
1 | some_array.reduce(x) do |a,b| a.some_method(b) end |
可以更简单地重写为:好的。
1 | some_array.reduce(x, &:some_method) |
而且因为Ruby中的
1 2 | [1,2,3].reduce(0, &:+) #=> 6 |
号
接下来,
1 2 | [1,2,3].reduce(&:+) #=> 6 |
最后,在传递一个不是文本代码块的块时,通常需要
一些方法,包括
1 2 3 4 5 | irb(main):001:0> [-1,2,-3].map(:abs) ArgumentError: wrong number of arguments (1 for 0) from (irb):1:in `map' from (irb):1 from /usr/bin/irb:12:in `<main>' |
。
所以我总是使用
1 2 | irb(main):002:0> [-1,2,-3].map(&:abs) #=> [1, 2, 3] |
Ruby有很多很好的在线教程。有关map/reduce和相关概念以及如何将它们应用于解决问题的更多一般信息,您应该搜索"函数编程"的介绍,之所以称之为"函数编程",是因为它将"函数"(即在Ruby中实现为
在Ruby中,最惯用的方法可能是:
1 | nums.inject(:+) |
. …虽然这基本上隐藏了所有的工作,所以这取决于测试试图测试什么。
数组注入文档