【问题标题】:Ruby calculate the percentage of elements in hashRuby计算哈希中元素的百分比
【发布时间】:2017-10-07 22:16:16
【问题描述】:

我有一个哈希:

hash = {"str1"=>2, "str2"=>3, "str3"=>7}

我想计算散列中每个元素的百分比,这样我就可以得到这样的一个:

{"str1"=>16.66% , "str2"=>25.00%, "str3"=>58.33%}

对此有任何想法吗?谢谢

【问题讨论】:

  • 使用Hash#transform_values 来执行此操作。
  • 欢迎来到 Stack Overflow。请阅读“How to Ask”和“minimal reproducible example”以及链接页面和“How much research effort is expected of Stack Overflow users?”。你的问题问得不好。你搜索了吗?如果不是为什么?如果是这样,它在哪里以及为什么没有帮助?你写代码了吗?如果不是,为什么?如果是这样,演示您所询问的问题所需的最少代码是多少?
  • @theTinMan 谢谢。是的,我搜索并没有找到我正在寻找的东西,这就是我问的原因。我认为我的问题在我给出的例子中已经足够清楚了。我在询问后的几分钟内就得到了我需要的答案。我不知道为什么反对票是……
  • 将鼠标悬停在箭头上以查看它们的含义。如果你搜索过,你应该说出在哪里并解释为什么它没有帮助。这有助于我们避免重复您的努力来帮助您,并帮助其他人找到其他资源。在几分钟内获得答案意味着您应该等待,看看是否会出现更好的答案。所有社区大约需要 24 小时才能看到一个问题并制定答案。请记住,SO 不仅仅是为了解决您的问题,它也是为了记录未来每个人的解决方案,所以完整的问题很重要。

标签: ruby-on-rails ruby percentage ruby-hash


【解决方案1】:

你可以使用Enumerable#each_with_object:

sum = a.values.inject(0, :+) # or simply a.values.sum if you're on Ruby 2.4+
#=> 12
a.each_with_object({}) { |(k, v), hash| hash[k] = v * 100.0 / sum }
#=> {"str1"=>16.666666666666668, "str2"=>25.0, "str3"=>58.333333333333336}

%一起拥有它:

a.each_with_object({}) { |(k, v), hash| hash[k] = "#{(v * 100.0 / sum).round(2)}%" }
#=> {"str1"=>"16.67%", "str2"=>"25.0%", "str3"=>"58.33%"}

【讨论】:

  • @AndreyDeineko 非常感谢您!我添加了round(2),以便在昏迷后仅获得 2 个数字。你能否解释一下{ |(k, v), hash| hash[k] = ,以便我能更好地理解......谢谢
  • @media 我用文档链接编辑了答案。基本上,您遍历每个键值对 (k,v) 并且您正在动态创建一个新对象 ({}) - 哈希。所以在第一次迭代哈希之前是空的(它是我们给出的初始值)。在第一次迭代中,我们将hash["str1"] 设置为等于基于v (2) 计算的百分比。在下一次迭代中,我们将hash["str2"] 设置为 eq 下一次计算,依此类推。所以最后我们有了新的哈希对象。
  • 如果您习惯 sprintf,'%.2f%' % (v * 100.0 / sum) 可能更具可读性。
  • @EricDuminil 我 100% 肯定迟早有人会提到 :) 我曾经使用插值 - '%.2f%' 让我想起了我不太喜欢的 Java。但实际上,对于习惯它的人来说,它可能看起来更干净
  • 在现实生活中,您需要处理sum 等于零的情况。
【解决方案2】:

最佳答案恕我直言,不幸被删除:

total = hash.values.sum
hash.transform_values { |v| (v * 100.0 / total).round(2) }

哈希方法transform_values 相对未知,而这种情况正是它的用途。 (Ruby 2.4+ 或 Rails 4.2+)

@Ursus,如果你取消删除你的,我会删除它。请记住,这里的答案不仅适用于 OP,还适用于将来有相同问题的任何其他人。

【讨论】:

  • 非常感谢马克,但我的回答与安德烈的回答非常相似,我使用了令人惊叹的 transform_values 方法,这种方法太新了,无法在没有替代方案的情况下将其放入答案中:)
  • 嗯,我认为随着时间的推移它会变得越来越有用。我的一些需要特定版本 Ruby 的答案当时可能不太有用,但最终became among my highest scoring answers
【解决方案3】:

感谢@AndreyDeineko 的快速回答! 我尝试仅使用each 方法(而不是each_with_object,所以这是答案。

sum = hash.values.sum
result = {}
hash.each { |k,v| result[k] = (v*100.00/sum).round(2)}

%一起拥有它:

hash.each { |k,v| result[k] = (v*100.00/sum).round(2).to_s + "%"}

【讨论】:

    猜你喜欢
    • 2014-01-29
    • 2021-10-28
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2021-01-10
    相关资源
    最近更新 更多