【问题标题】:fill hash values with another hash用另一个哈希填充哈希值
【发布时间】:2019-08-13 16:49:26
【问题描述】:

我有一个带有更多值的哈希值:

hash1 = {
  :a => {
    :foo => 435,
    :bar => 3264
  },
  :b => {
    :foo => 45234,
    :bar => 2452
  },
  :c => {
    :foo => 4352,
    :bar => 4535
  }
}

我需要将 a、b 和 c 的总和添加到新数组中


hash2 = {
  :a => total,
  :b => total,
  :c => total
}

到目前为止,我的尝试是这样的: hash2.each {|e,v| v = hash1[0]}

苦苦挣扎,所以我需要一些帮助!谢谢!

【问题讨论】:

  • hash1.transform_values { |v| v.values.sum }
  • @AlekseiMatiushkin 仅适用于 ruby​​ 版本 >= 2.4
  • @lacostenycoder 2019 年了;如果有人问这样的问题,这显然意味着他们不支持传统的庞然大物,并且可以安装最新的 ruby​​ 版本。
  • @AlekseiMatiushkin,这是真的,我是最新的

标签: ruby


【解决方案1】:

如果您使用的是 Ruby 版本 >= 2.4,您可以这样做

hash2 = hash1.transform_values { |v| v.values.sum }
=>{:a=>3699, :b=>47686, :c=>8887}

感谢 @3limin4t0r 和 @Aleksei Matiushkin 为 Ruby 版本

hash2 = Hash[hash1.map { |k, v| [k, v.values.reduce(0, &:+)] }]
=> {:a=>3699, :b=>47686, :c=>8887}
# or if your prefer each_with_object
hash1.each_with_object({}) { |(k, v), h| h[k] = v.values.reduce(0, &:+) }
=> {:a=>3699, :b=>47686, :c=>8887}

原件留在这里交流

否则你可以这样做,可能有更快的方法,但它有效

hash2 = {}
sum_vals = hash1.values.map{|h| h.values.inject(&:+)}
hash1.keys.each_with_index{|key, i| hash2[key] = sum_vals[i] }
hash2
=>{:a=>3699, :b=>47686, :c=>8887}

【讨论】:

  • 对于旧版本我会使用Hash[hash1.map { |k, v| [k, v.values.reduce(0, :+)] }]
  • @AlekseiMatiushkin 让我们更彻底地清理它hash1.each_with_object({}) { |(k, v), h| h[k] = v.values.reduce(:+) }
  • @engineersmnky stackoverflow.com/questions/57441885/… — 我总是明确指定初始值 以阐明意图(通过块。)reduceinject 接受符号完全错误。
  • @AlekseiMatiushkin 虽然我可以承认将符号传递给reduce 确实会让人感觉有点脏:)。所有答案都已经建立在给定结构的基础上,因此 IMO 的初始值既不存在也不存在。如果v 不是Hash 那么values 消息的结果是不确定的,sumreduce 更是如此。例如,values 应该实际上导致Array<String>Array<Array> 然后reduce(0,&:+) 将引发TypeErrorsum 也会引发)但reduce(&:+) 不会。
  • @lacostenycoder 它在相同的假设下运行,但灵活性较低。 sum 假定 Integer 并且需要一个初始值,除非 obj.all?(Numeric)。这意味着,要利用 sum 与数字以外的东西,你最知道那是什么和/或传递一个块来转换那个东西(本质上是map(&method).sum(initial)),例如{foo: 1, bar: 2}.sum(&:pop) #=> 3 但是{foo: 1, bar: 2}.sum("",&:to_s) #=> "[:foo, 1][:bar, 2]"{foo: 1, bar: 2}.sum([]) #=> [:foo,1,:bar,2]
【解决方案2】:

是的,Aleksei Matiushkin 是完全正确的。 transform_values 有破坏性版本和非破坏性版本。破坏性版本具有所谓的 bang 或感叹号,因此:transform_values! 被读取为转换值 bang,它会改变您的原始哈希。另一方面,transform_values 返回一个新数组而不改变原始数组,因此是非破坏性的。据我所知,您想处理非破坏性版本。

在这种情况下,您可以运行hash1.transform_values { |values| values.values.sum },它将返回新的哈希值,但是,由于这是非破坏性的,hash1 仍将等于您原来的hash1。因此,您希望将hash2 设置为等于变换值。

基本上发生的事情是散列遍历与键关联的所有值并获取这些键值(由于您具有多维散列)并将它们加在一起。

这里有一个很棒的链接供您查看! https://blog.bigbinary.com/2017/06/14/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support.html

【讨论】:

  • 不错,但 Ruby 版本
猜你喜欢
  • 2013-07-21
  • 2020-02-20
  • 1970-01-01
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-16
相关资源
最近更新 更多