【问题标题】:Merge array of hashes with validation将哈希数组与验证合并
【发布时间】:2014-02-19 13:54:02
【问题描述】:

如果某些键匹配,我想将一个哈希数组与另一个合并。例如,我有这个:

data = [{"a"=>1, "b"=>2, "c"=>3}, {"a"=>1, "b"=>5, "c"=>7}]
new_data = [{"a"=>1, "b"=>2, "z"=>10}]

运行一些方法,像这样:

merge_with_validation(data, new_data, ["a","b"])

我希望结果是这样的:

[{"a"=>1, "b"=>2, "c"=>3, "z"=>10}, {"a"=>1, "b"=>5, "c"=>7, "z"=>nil}]

所以当键 ab 中的值匹配时,结果是 datanew_data 合并。


答案更新

我使用 Arup Rakshit 的回答做了一点改动:

def merge_with_validation(data, new_data, keys)
  data.map do |hash|
    if hash.values_at(*keys) ==  new_data.first.values_at(*keys)
      next hash.merge(new_data.shift)
    end
    hash
  end
end

【问题讨论】:

  • 问题不清楚,keya的值怎么计算为2?到目前为止,您还尝试过什么?
  • 最重要的是,您的预期结果的第二种形式无效。
  • 最重要的是,merge 是对哈希的操作,而不是对数组的操作。你的最后一句话没有意义。
  • 修正了预期结果
  • new_data 中可以有多个哈希值吗?

标签: ruby arrays hash


【解决方案1】:

我愿意

data = [{"a"=>1, "b"=>2, "c"=>3}, {"a"=>1, "b"=>5, "c"=>7}]
new_data = [{"a"=>1, "b"=>2, "z"=>10}]

def merge_with_validation(data, new_data, keys)
    data.map do |hash|
       if hash.values_at(*keys) ==  new_data.first.values_at(*keys)
           next hash.merge(new_data.first)
       end
       hash.merge({"z"=>nil})
    end
end

merge_with_validation(data, new_data, ["a","b"]) 
# => [{"a"=>1, "b"=>2, "c"=>3, "z"=>10}, {"a"=>1, "b"=>5, "c"=>7, "z" => nil}]

【讨论】:

  • 很好地使用values_at! :-) +1
  • @Abdo 谢谢.. :-)
  • 您好,谢谢您的回答!你的代码满足了我的需求。我刚刚做了一个更改,你把 hash.merge({"z"=>nil}) 替换为 hash 因为如果行不匹配,我真的不需要 nil 值。
  • @victorkohl 是的,如果您不需要"z" => nil},只需使用hash 而不是hash.merge({"z"=>nil})
  • 另一个更改是next hash.merge(new_data.first) 我更改为next hash.merge(new_data.shift),所以new_data 可以有多个哈希值。谢谢!
【解决方案2】:

这个怎么样:

请注意,我们不会以编程方式检查丢失的键(即“z”),但我们可以这样做

def merge_with_validation(data, new_data, keys)
    data.each_with_object([]).with_index { |(e,arr), i| 
       new_hash = new_data[i] || e
       new_hash["z"] = nil if !new_hash["z"]
       arr << e.merge(new_hash) if keys.all? { |k| e[k] ==  new_hash[k]} 
    }
end

返回:

merge_with_validation(data,new_data, %w(a b))
=> [{"a"=>1, "b"=>2, "c"=>3, "z"=>10}, {"a"=>1, "b"=>5, "c"=>7, "z"=>nil}]

如果您发现错误,请告诉我,我会修复(我踢足球要迟到了 :-))

【讨论】:

  • 您好,感谢您的回答。此代码适用于我提供的示例,但是当它与某些行不匹配时,其余的将不会被合并。例如:data = [{"a"=&gt;1, "b"=&gt;2, "c"=&gt;3}, {"a"=&gt;1, "b"=&gt;5, "c"=&gt;7}]new_data = [{"a"=&gt;1, "b"=&gt;5, "z"=&gt;10}]。预期的结果是 [{"a"=&gt;1, "b"=&gt;2, "c"=&gt;3}, {"a"=&gt;1, "b"=&gt;5, "c"=&gt;7, "z"=10}],但它只返回 data 中匹配的行 ({"a"=&gt;1, "b"=&gt;5, "c"=&gt;7, "z"=10}])。
  • 我看到你想在进行某种组合时合并。除非我像你上面那样做下一个班次,否则我的修复将不起作用。我将删除:-)
猜你喜欢
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
  • 2021-12-12
  • 2019-07-26
  • 2016-10-07
  • 1970-01-01
相关资源
最近更新 更多