将修改后的Ruby数组生成块

时间:2017-01-23 18:46:57

标签: arrays ruby methods

我试图将2行ruby代码转换为1.例如:

def average(numbers)
  result = numbers.compact
  numbers.reduce(+) / numbers.length
end

我一直在寻找阵列方法,而且无法找到合适的方法将此功能转变为单线程。我曾希望这样的事情会起作用:

def average(numbers)
  numbers.compact.<tap or another method> { |arr| arr.reduce(+) / arr.length }
end

基本上,我正在修改数组(在示例中我必须调用compact以取消nil值),所以我无法访问数组变量,而且我没有&# 39;我想要一个迭代器,因为我不想在数组的各个元素上调用reduce(+)length

有没有人知道我可以研究的方法?

2 个答案:

答案 0 :(得分:2)

我认为您的方法是:reduce(:+),而不是reduce(+)并在第二行使用result而不是numbers

def average(numbers)
  result = numbers.compact
  result.reduce(:+) / result.length
end

average [1,2,3]
  #=> 2

如果您希望平均值为浮点数,请将第二行更改为

result.reduce(0.0, :+) / result.length

有多种方法可以组合方法的两行,但我不喜欢它们中的任何一种。这里有几个。 (我不知道Object#tap如何在这里使用。)

numbers.compact.reduce(:+) / numbers.compact.length

(result = numbers.compact).reduce(:+) / result.compact.length

numbers.map(&:to_i).reduce(:+) / numbers.compact.length

请注意,即使numbers可以变异,也无法写

numbers.compact!.reduce(:+) / numbers.length

因为如果numbers.compact!不包含nil元素,numbers会返回nil

在Ruby v2.4 +中,您可以使用Array#sum

result.sum / result.length

答案 1 :(得分:0)

您可以更改拨打average

的方式
def average(numbers)
  numbers.reduce(:+) / numbers.length
end

average(num_array.compact)