【问题标题】:Sum of particular values in a Ruby hashRuby 哈希中特定值的总和
【发布时间】:2017-04-04 16:24:33
【问题描述】:

我有两个哈希:

first = { 1 => [15, 15, 15, 8], 4 => [11, 12, 7, 7], 5 => [14, 17, 13, 13],
          6 => [19, 19, 15, 15], 7 => [5, 12, 12, 12], 8 => [10, 14, 14, 14], 
          9 => [8, 7, 8, 8] } 

second = { 1 => [0, 1, 2], 4 => [2, 3], 5 => [2, 3], 6 => [0, 1, 2, 3], 
           7 => [1, 2, 3], 8 => [1, 2, 3], 9 => [2, 3] }

如您所见,它们都使用相同的键,但值不同。 second 的值包含first 值的索引范围,我只需要对这些范围内的first 值求和。

预期输出:

result = { 1 => [45], 4 => [14], 5 => [26], etc }

【问题讨论】:

  • 正确解释这个结果 = { 1 => [45], 4 => [14], 5 => [26], etc }
  • 您遇到问题的代码是什么? Stack Overflow 不是为我写代码的服务。那些确实存在,他们被称为“程序员”,你可以付费雇佣他们。

标签: ruby sum ruby-hash


【解决方案1】:

直截了当的方法是准确地说出你的意思:

first.map { |k, v| [ k, [ v.values_at(*second[k]).sum ] ] }.to_h

如果您的 Ruby 版本没有 Array#sum,请使用 inject(:+)

first.map { |k, v| [ k, [ v.values_at(*second[k]).inject(:+) ] ] }.to_h

您也可以改用each_with_object 跳过map/to_h 业务:

first.each_with_object({}) { |(k, v), h| h[k] = [ v.values_at(*second[k]).inject(:+) ] }

Array#values_at documentationEnumerable documentation 的相处时间可能会有所收获。

【讨论】:

  • ?,为什么将每个总和都包含在一个数组中?我看到@llya 做了同样的事情,所以我可能遗漏了一些东西。
  • @CarySwoveland 因为这是问题要求的格式。我同意它看起来有点奇怪但是......
  • Egad,我怎么错过了?
【解决方案2】:

更自然的方式是使用Hash#merge,我认为:

first.merge(second) { |_, f, s| [f.values_at(*s).sum] }
#=> {1=>[45], 4=>[14], 5=>[26], 6=>[68], 7=>[36], 8=>[42], 9=>[16]}

当然,如果您的 Ruby 版本 ,您可以使用 inject(:+) 而不是 sum

【讨论】:

    【解决方案3】:

    既然你说second 的元素是范围,你可以这样写:

    second = { 1=>0..2, 4=>2..3, 5=>2..3, 6=>0..3, 7=>1..3, 8=>1..3, 9=>2..3 }
    

    然后

    second.merge(second) { |k,o,_| first[k].values_at(*o).sum }
      #=> {1=>45, 4=>14, 5=>26, 6=>68, 7=>36, 8=>42, 9=>16}
    

    这使用Hash#merge 的形式,它使用一个块来确定在被合并的两个散列中存在的键的值,这里是所有键。有关详细信息,请参阅文档,特别是三个块变量 kon 的值。 (这里我将n 替换为_ 表示它不用于块计算。)

    【讨论】:

      【解决方案4】:

      试试这个:

      def sum(list, indices)
          sum = 0
          indices.each do |index|
              sum += list[index]
          end
         return sum
      end
      

      然后

      second.map { |k, v| [k, sum(first[k], v)] }.to_h

      【讨论】:

        猜你喜欢
        • 2019-08-07
        • 2015-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        • 2021-12-09
        • 2013-10-01
        相关资源
        最近更新 更多