【问题标题】:How do you concisely get the average house price from an array of houses?如何简明扼要地从一系列房屋中获得平均房价?
【发布时间】:2009-07-23 01:19:03
【问题描述】:

假设@houses 数组设置如下:

house1.price = 10
house2.price = 20
house3.price = 30
@houses << house1
@houses << house2
@houses << house3

这是我们计算的起点,我们要找到房子的平均价格:

total = 0
average = 0
for h in @houses
 total += h.price
end
average = total/@houses.size

这似乎是为了得到一个平均数。

有没有更好的办法?

【问题讨论】:

    标签: ruby arrays average


    【解决方案1】:

    对可枚举集合使用inject 方法。 Inject 允许您为“累加器”传入一个初始值(在本例中为 0),然后对列表中的每个元素应用一些操作,并为累加器返回一个新值,以将其传递到下一次迭代中。

    累加器的最终值随后从inject 调用中返回。

    所以在这种情况下,我们只是将所有房价加到累加器中,然后最后除以总数。

    您可以变得更有趣,并且可能使用一些 Ruby Skillz 将其压缩得更多,但这是可以理解的,并且只遍历列表一次以将值相加。

    @houses.inject(0){|total, house| total + house.price} / @houses.size
    

    【讨论】:

      【解决方案2】:

      Madlep 的答案适用于过去几年的任何 Ruby 版本。但如果您使用的是 Ruby 1.8.7 或更高版本,则可以更简洁地表示为 @houses.collect(&amp;:price).inject(:+)/@houses.size

      顺便说一句,我曾假设这种技术会更慢,因为它必须循环两次,但由于 Ruby 本身的优化,在我对 Ruby 1.8.7 的测试中,它实际上要快得多,最多可达几百万个项目,而且更快(但没有那么多)甚至超过 Ruby 1.9 中的 1000 万个项目。向您展示分析的重要性。

      【讨论】:

      • 嗨查克。我一直在“The Ruby Programming Language”中寻找您在此处给出的语法的解释,但我无法弄清楚这些特殊字符的用途。你介意告诉我 &:price 是什么意思,以及 inject(:+) 谢谢。
      • 这是 Ruby 1.8.7 和 1.9 中的新功能。对于任何需要一个块的方法,你可以传递&amp;:somemethod,它相当于写{|object| object.somemethod}。至于:+,它告诉inject 对数组中的所有对象调用+ 并累加结果,就像写inject{|memo, obj| memo+obj} 一样。这有意义吗?
      • 不知道他们在 1.9 中添加了这个。太棒了:D
      • 啊。我得到它。我在有关注入 + 减少的 ruby​​ 文档部分找到了一些示例。谢谢你的解释。我很想使用它,但遗憾的是我无法将我的项目升级到 1.87。
      • 我认为madlep 的回答非常好。但是,如果您确实想在较旧的 Ruby 中使用 &amp;:methodname 语法,您可以实现:class Symbol; def to_proc() @proc_version ||= proc {|r, *a| r.send self, *a} end end。它不会像 1.9 版本那么快,但在功能上是一样的。
      【解决方案3】:

      如果你在 Rails 应用中,你可以做 array.sum/array.size

      【讨论】:

      • .sum 仅适用于数字数组。如果您阅读该问题,则 OP 有一组房屋对象,而不是数字。
      猜你喜欢
      • 1970-01-01
      • 2017-10-18
      • 2020-04-09
      • 1970-01-01
      • 2016-05-27
      • 2014-01-17
      • 2018-09-05
      • 2012-10-30
      • 2018-07-17
      相关资源
      最近更新 更多