I have an array of hashes within an array of hashes. I'd like to remove duplicates based on the values of the inner arrays.
我在哈希数组中有一个哈希数组。我想根据内部数组的值删除重复项。
topics = [{"defense"=>
[{:id=>30,
:source=>"Hacker News",
:title=>
"China-based campaign breached satellite, defense companies: Symantec",
:link=>
"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]},
{"companies"=>
[{:id=>30,
:source=>"Hacker News",
:title=>
"China-based campaign breached satellite, defense companies: Symantec",
:link=>
"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]},
{"Symantec"=>
[{:id=>30,
:source=>"Hacker News",
:title=>
"China-based campaign breached satellite, defense companies: Symantec",
:link=>
"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]}]
topics.uniq { |phrase, post| post }
puts topics
You can see above that the phrases defense
, companies
, and Symantec
each contain identical arrays. How can I keep only the first hash that contains one of the identical arrays?
您可以在上面看到,防御,公司和Symantec的短语都包含相同的数组。如何只保留包含其中一个相同数组的第一个哈希?
Expected output:
{"defense"=>
[{:id=>30,
:source=>"Hacker News",
:title=>
"China-based campaign breached satellite, defense companies: Symantec",
:link=>
"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]}
Note: in the above example each inner array of "phrases" only contains one hash, but in the application it could contain several posts.
注意:在上面的例子中,“短语”的每个内部数组只包含一个哈希,但在应用程序中它可以包含几个帖子。
3 个解决方案
#1
2
topics.invert.invert
will reduce the hash to a single (arbitrarily-chosen) key for each unique value.
topics.invert.invert会将哈希值减少为每个唯一值的单个(任意选择)键。
#2
0
With this solution you get only the array:
使用此解决方案,您只获得数组:
topics.map { |topic| topic.values }.uniq.flatten
It returns just:
它只返回:
# => [{:id=>30, :source=>"Hacker News", :title=>"China-based campaign breached satellite, defense companies: Symantec", :link=>"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]
#3
0
topics = [
{ "defense" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] },
{ "companies" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] },
{ "Symantec" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] }
]
topics.uniq { |h| h.values }
#=> [{"defense"=>[{:id=>30, :source=>"Hacker", :title=>"China", :link=>"F2X0"}]}]
See Array#uniq for the case when uniq
employs a block. Note the sentence, "self
is traversed in order, and the first occurrence is kept."
有关uniq使用块的情况,请参阅Array #uniq。请注意句子“按顺序遍历自我,并保留第一次出现”。
#1
2
topics.invert.invert
will reduce the hash to a single (arbitrarily-chosen) key for each unique value.
topics.invert.invert会将哈希值减少为每个唯一值的单个(任意选择)键。
#2
0
With this solution you get only the array:
使用此解决方案,您只获得数组:
topics.map { |topic| topic.values }.uniq.flatten
It returns just:
它只返回:
# => [{:id=>30, :source=>"Hacker News", :title=>"China-based campaign breached satellite, defense companies: Symantec", :link=>"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]
#3
0
topics = [
{ "defense" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] },
{ "companies" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] },
{ "Symantec" => [{ id: 30, source: "Hacker", title: "China", link: "F2X0"}] }
]
topics.uniq { |h| h.values }
#=> [{"defense"=>[{:id=>30, :source=>"Hacker", :title=>"China", :link=>"F2X0"}]}]
See Array#uniq for the case when uniq
employs a block. Note the sentence, "self
is traversed in order, and the first occurrence is kept."
有关uniq使用块的情况,请参阅Array #uniq。请注意句子“按顺序遍历自我,并保留第一次出现”。