如果两个单独的哈希中的键相等,则创建两个键值的交集。红宝石

发布于 2024-10-03 21:03:14 字数 1093 浏览 1 评论 0原文

我正在尝试创建 hash1 的值与 hash2 的值的交集(如果这些值共享相同的键)。到目前为止,这是我的代码。我能够生成两个哈希值 -->数据和数据1.

#!/usr/bin/env ruby

require 'pp'
require 'set'
data = {}
File.read(ARGV[0]).each do |l|
  l.chomp!
  key, value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12 = l.split(/\s+/)
  data[key] ||= {}
  values = [value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12]
  data[key] = values.compact!

end

data1 = {}
File.read(ARGV[1]).each do |l|
  l.chomp!
  value = l.split(/\s+/)
  data1[value[0]] ||= {}
  data1[value[0]] = [value] 
end

因此,我的主要目标是对于 hash1 中的每个键,仅保留 hash2 中相同键中也存在的那些值,否则从 hash1 中删除这些值。顺便说一句,我不关心 Hash2 中存在但 Hash1 中不存在的任何键。

我知道数组可以使用“&”相交和“设置”,尽管到目前为止我还无法在我的脚本中完成此操作。

任何建议都会很棒。谢谢。

对于西奥:

是的。
hash1 { alpha: [a,b,c,d,e], bravo: [f,g,h,i,j], charlie: [k,l,m,n,o], delta:[p,r ]}

hash2 { alpha: [a,c,q,z], bravo: [z,x], charlie: [k,l,m,n]}

所以,交集看起来像这样。

hash3 { alpha: [a,c], bravo:[nil], charlie: [k,l,m,n]}

I am trying to create an intersection of the values of hash1 with those of hash2, if those values share the same key. Here is my code so far. I am able to generate two hashes --> data and data1.

#!/usr/bin/env ruby

require 'pp'
require 'set'
data = {}
File.read(ARGV[0]).each do |l|
  l.chomp!
  key, value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12 = l.split(/\s+/)
  data[key] ||= {}
  values = [value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12]
  data[key] = values.compact!

end

data1 = {}
File.read(ARGV[1]).each do |l|
  l.chomp!
  value = l.split(/\s+/)
  data1[value[0]] ||= {}
  data1[value[0]] = [value] 
end

So, my main goal is for each key in hash1, keep only those values that also are present at that identical key in hash2, otherwise remove those values from hash1. I am not concerned with any keys present in Hash2 that are not present in Hash1, btw.

I know arrays can be intersected using "&" and "set", though I have not been able to accomplish this in my script so far.

Any advice would be great. Thanks.

For Theo:

Yes.
hash1 { alpha: [a,b,c,d,e], bravo: [f,g,h,i,j], charlie: [k,l,m,n,o], delta:[p,r]}

hash2 { alpha: [a,c,q,z], bravo: [z,x], charlie: [k,l,m,n]}

So, the intersection would look like this.

hash3 { alpha: [a,c], bravo:[nil], charlie: [k,l,m,n]}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

┈┾☆殇 2024-10-10 21:03:14

对于两个哈希值的常规交集,请执行以下操作:

Hash[h1.to_a & h2.to_a]

但是您的情况有点不同。您可以使用以下代码获得您正在寻找的交集:

hash1 = {:alpha => [:a,:b,:c,:d,:e], :bravo => [:f,:g,:h,:i,:j], :charlie => [:k,:l,:m,:n,:o], :delta => [:p,:r]}
hash2 = {:alpha => [:a,:c,:q,:z], :bravo => [:z,:x], :charlie => [:k,:l,:m,:n]}

common_keys = hash1.keys & hash2.keys 
  # => [:alpha, :bravo, :charlie]
intersection = common_keys.map { |k| [k, hash1[k] & hash2[k]] } 
  # => [[:alpha, [:a, :c]], [:bravo, []], [:charlie, [:k, :l, :m, :n]]]
intersection = intersection.reject { |k, v| v.empty? } 
  # => [[:alpha, [:a, :c]], [:charlie, [:k, :l, :m, :n]]]
Hash[intersection]
  # => {:alpha=>[:a, :c], :charlie=>[:k, :l, :m, :n]}

您的示例包括 :bravo =>; [nil],但我认为这是一个错误,因为 nil 不是 hash1:bravo 键之间的公共元素和hash2,所以它没有意义。如果您想要 hash1hash2 中的键的空列表,但其值列表中没有公共元素,您可以删除第三行,否则会删除这些元素。

For a regular intersection of two hashes do:

Hash[h1.to_a & h2.to_a]

But your case is a little bit different. You can get the intersection you are looking for with this code:

hash1 = {:alpha => [:a,:b,:c,:d,:e], :bravo => [:f,:g,:h,:i,:j], :charlie => [:k,:l,:m,:n,:o], :delta => [:p,:r]}
hash2 = {:alpha => [:a,:c,:q,:z], :bravo => [:z,:x], :charlie => [:k,:l,:m,:n]}

common_keys = hash1.keys & hash2.keys 
  # => [:alpha, :bravo, :charlie]
intersection = common_keys.map { |k| [k, hash1[k] & hash2[k]] } 
  # => [[:alpha, [:a, :c]], [:bravo, []], [:charlie, [:k, :l, :m, :n]]]
intersection = intersection.reject { |k, v| v.empty? } 
  # => [[:alpha, [:a, :c]], [:charlie, [:k, :l, :m, :n]]]
Hash[intersection]
  # => {:alpha=>[:a, :c], :charlie=>[:k, :l, :m, :n]}

Your example includes :bravo => [nil], but I think that is an error since nil is not a common element between the :bravo key in hash1 and hash2, so it doesn't make sense. If you want an empty list for keys that are in hash1 and hash2 but have no common elements in their value lists you can remove the third line, which otherwise removes those.

思念满溢 2024-10-10 21:03:14
data  = { a: [11], b: [22, 222], c: [33] }
data2 = { b: [222, 2222], d: [4444] }

Hash[data.map {|k, v| if data2[k] then [k, v & data2[k]] end }.compact]
# => { b: [222] }
data  = { a: [11], b: [22, 222], c: [33] }
data2 = { b: [222, 2222], d: [4444] }

Hash[data.map {|k, v| if data2[k] then [k, v & data2[k]] end }.compact]
# => { b: [222] }
追我者格杀勿论 2024-10-10 21:03:14
def merge_hash(hash1, hash2)
  result = {}

  hash1.keys.each do |k|
    result[k] = hash1[k] & hash2[k] unless hash2[k].nil?
  end
  result
end
def merge_hash(hash1, hash2)
  result = {}

  hash1.keys.each do |k|
    result[k] = hash1[k] & hash2[k] unless hash2[k].nil?
  end
  result
end
方觉久 2024-10-10 21:03:14
Hash[h2.collect { |k,v| h1[k] ? [k, h1[k] & h2[k]] : [] }]

此外,您首先检查 h1.keys 与 h2.keys 的大小进行比较,然后首先迭代较小的一个。它失去了上面的一些清晰度,但对于大小不同的较大散列来说,它会表现得更好。

Hash[h2.collect { |k,v| h1[k] ? [k, h1[k] & h2[k]] : [] }]

Additionally, you check the size of h1.keys compared to h2.keys first and then iterate over the smaller one first. It loses a bit of the clarity of the above, but it will perform a lot better for larger hashes with a disparity in sizes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文