【问题标题】:Find duplicated values in an Array of Hashes在哈希数组中查找重复值
【发布时间】:2016-08-31 08:46:54
【问题描述】:

我正在寻找一种仅从多个哈希数组中选择重复条目的方法。

假设我有一个属性名为“exchange_rate”的项目:

project.exchange_rate #=>
    [{"name"=>"USD", "rate"=>1.0},
     {"name"=>"EUR", "rate"=>0.91},
     {"name"=>"CNY", "rate"=>6.51},
     {"name"=>"NOK", "rate"=>1},
     {"name"=>"DKK", "rate"=>1},
     {"name"=>"JPY", "rate"=>113.24}]

现在我有多个具有相同结构的项目,只是数组中的条目更多/更少。哈希中的“比率”根本不重要。我只需要遍历所有项目及其 exchange_rates 并找到每个数组中的条目。

可以这么说,如果我有以下项目_2:

project_2.exchange_rate #=>
    [{"name"=>"USD", "rate"=>1.0},
     {"name"=>"GBP", "rate"=>0.7},
     {"name"=>"SGD", "rate"=>1.38},
     {"name"=>"HKD", "rate"=>7.76},
     {"name"=>"CNY", "rate"=>0.94},
     {"name"=>"DE", "rate"=>0.86},
     {"name"=>"JPY", "rate"=>113.24}]

比较这两个条目后,我想得到一个如下所示的数组:

# => ["USD", "CNY", "JPY"]

因为这三个名字都在两个项目中。当然,这应该是动态的,并且适用于任意数量的项目和汇率。

我似乎找不到这样做的方法。 我已经尝试了以下方法:

er = projects.map { |e| e[:exchange_rate] }.inject(:+)
founds = er.find_all { |x| er.count(x) > 1 }.uniq

但它提供了一个巨大的数组,其中包含所有类型的值,而不仅仅是重复值。

TL;DR:

  • 我需要遍历所有项目及其汇率

  • 我需要找到这些的所有重复条目

  • 我最终只需要这些的“名称”值

  • 我有未知数量的项目以及绑定到每个项目的 exchange_rates

非常感谢您!


我认为这并不完全是我所需要的,所以我改变了主意并采取了不同的做法。 尽管如此,这个问题对于其他人来说可能是可行的。如果您有答案,请继续发布:)

我的(完全题外话)结果:

names = projects.map{|p| p[:exchange_rates].map{|er| er["name"] } }
final = names.flatten.uniq
# from => [["USD", "EUR", "GBR"], [], ["MYR", "GBR"], ["USD"], ...]
# to ["USD", "EUR", "GBR", "MYR"]

【问题讨论】:

  • 你的第一个方法很接近。您应该考虑两件事:(1)您只关心 e[:exchange_rate].map{|r| r["name"]} 中元素的唯一性,而不仅仅是 e[:exchange_rate. (2) 尝试在& 运算符中查找Array。这会在两个数组之间找到共同的元素,而 + 只是将它们加在一起,这就是为什么你最终会得到一个巨大的数组。
  • 好的。我想出了如何获取“名称”值,但是现在我仍然得到了一个数组数组,我需要遍历并在所有数组之间应用 & 。这不仅听起来效率极低,而且我似乎也找不到自动执行此操作的方法。
  • 在不考虑效率的情况下(而且我认为这并没有那么糟糕,因为数据大小似乎有限),尝试调整您的inject(:+)。这对每个元素依次执行:+。在这里,我们正在寻找:&
  • 只是为了探索:为了提高计算效率,我可能会根据name 值构造一个带有键的哈希。您可以计数,或者对于更少的操作,第一次将值 1 添加到 Hash fir,第二次看到名称时添加 2,并且永远不要再更改该键的值。然后,最后,您可以扫描 Hash 以查找 2(或 > 1)的值
  • 啊啊啊,明白了!我的想法朝着完全不同的方向发展。非常感谢! :)

标签: arrays ruby-on-rails-4 hash


【解决方案1】:

您可以简单地使用project_1.exchange_rate & project_2.exchange_rate ,它为您提供[{"name"=>"USD", "rate"=>1.0}, {"name"=>"JPY", "rate"=>113.24}],即来自两个数组的共同条目,其键和值在两个数组中都匹配。

但是,如果您只想查找两个数组中哈希键的共同元素,您可以尝试这样的方法

project_1.exchange_rate.map {|e| e["name"]} & 
project_2.exchange_rate.map {|e| e["name"]}

#=> ["USD", "CNY", "JPY"]

如果您像您所说的那样有多个数组,请尝试以下操作:

def get_duplicate_keys(*rates)
    all_rates = rates.inject([]) { |s, e| s + e }
    temp = all_rates.group_by { |e| e["name"] }
    temp.select { |k,v| v.count > 1 }.keys
end

r1 = [{"name"=>"USD", "rate"=>1.0}, 
            {"name"=>"EUR", "rate"=>0.91}, 
            {"name"=>"CNY", "rate"=>6.51}, 
            {"name"=>"NOK", "rate"=>1}, 
            {"name"=>"DKK", "rate"=>1}, 
            {"name"=>"JPY", "rate"=>113.24}]
r2 =  [{"name"=>"USD", "rate"=>1.0}, 
            {"name"=>"GBP", "rate"=>0.7}, 
            {"name"=>"SGD", "rate"=>1.38}, 
            {"name"=>"HKD", "rate"=>7.76}, 
            {"name"=>"CNY", "rate"=>0.94}, 
            {"name"=>"DE", "rate"=>0.86}, 
            {"name"=>"JPY", "rate"=>113.24}]
r3 =  [{"name"=>"GBP", "rate"=>0.7}, 
            {"name"=>"SGD", "rate"=>1.38}]

p get_duplicate_keys(r1 + r2 + r3)

#=> ["USD", "CNY", "JPY", "GBP", "SGD"]

【讨论】:

  • 问题是,正如我所说,我没有两个这样的项目,而只有二十到三十个。
  • @PhilM。检查多个数组的更新答案。这可能会有所帮助!
【解决方案2】:

你可以试试这个解决方案,

duplicates = project.exchange_rate & project_2.exchange_rate

然后

duplicates.map{|er| er["name"]}

这会返回结果

=> ["USD", "CNY", "JPY"]

或者您可以尝试以下解决方案.....

首先,您会找到两个项目的名称数组

proj1_names = []
project.exchange_rates.each{ |er| proj1_names << er["name"] }

proj2_names = []
project_2.exchange_rates.each{ |er| proj2_names << er["name"]}

这给出了类似的结果

proj1_names = ["USD","EUR","CNY","NOK","DKK","JPY"]
proj2_names = ["USD","GBP","SGD","HKD","CNY","DE","JPY"]

然后试试下面的方法

proj1_names.select{|name| proj2_names.include?(name)}

这将返回重复的名称作为结果

i.e => ["USD", "CNY", "JPY"]

希望对你有帮助..

【讨论】:

  • 就像发布的另一个答案一样,这对我没有多大帮助,因为我有两个以上的项目。我确实有 20-30 个项目,而且数量几乎在不断变化。
猜你喜欢
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 2017-01-19
相关资源
最近更新 更多