Arrays Ruby-如何删除哈希数组中的重复项?
我在一个哈希数组中有一个哈希数组。我想根据内部数组的值删除重复项Arrays Ruby-如何删除哈希数组中的重复项?,arrays,ruby,Arrays,Ruby,我在一个哈希数组中有一个哈希数组。我想根据内部数组的值删除重复项 topics = [{"defense"=> [{:id=>30, :source=>"Hacker News", :title=> "China-based campaign breached satellite, defense companies: Symantec", :link=> "https://www.reuters.com/
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
您可以在上面看到短语defence
、companys
和Symantec
都包含相同的数组。如何仅保留包含一个相同数组的第一个哈希
预期产出:
{"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"}]}
注意:在上面的示例中,“短语”的每个内部数组只包含一个散列,但在应用程序中,它可能包含多个帖子。
主题。invert.invert
会将散列减少为每个唯一值的单个(任意选择的)键。使用此解决方案,您只会得到数组:
topics.map { |topic| topic.values }.uniq.flatten
它只返回:
# => [{: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"}]
有关
uniq
使用块的情况,请参阅。注意这句话,“self
按顺序遍历,并保留第一次出现的内容。”如果删除这些额外的数组,处理数据可能会更容易,即topics={“defence”=>{id:30,…},“companys”=>{id:30,…}
。只是说;-)@stefan我有没有办法做到这一点并保持每个短语包含多个帖子的能力?在上面的例子中,我只展示了一篇链接到短语“defence”的文章,但实际上该短语下可能有多篇文章。然后你可以有{“defence”=>[{…},{…}],“companys”=>[…]}
,但没有必要将每一对短语文章包装在一个单独的散列中。似乎主题
应该是一个包含主题的散列。键
返回[“防御”、“公司”、“赛门铁克”]
也许您可以根据实际值稍微调整您的示例,即添加一些对所有短语通用的帖子和其他独特的帖子。然后展示你的预期结果。也许您可以减少示例数据量,例如,只需:id
和一个简短的:title
。如果主题值包含多个项目,会发生什么情况?数组
应该是唯一的,还是生成的散列
应该只出现一个值?现在,如果将完整的数组
视为值和唯一性要求,则这将起作用<代码>主题.map(&:values).uniq.map{| v | topics.find{| h | h.values==v}}。但是,可以通过将reduce(&:merge)
链接到末尾来获得到散列的转换,但是如果一个键在具有不同值的主题中出现超过1次,则将该数组
转换为散列似乎适得其反,topics
是一个数组,值分布在不同的散列中。啊<代码>主题。注入(:合并)。反转。反转
?:/这不是武断的,它将是最后一个结果,在这种情况下,将是“Symantec”
而不是“defense”
,正如问题所示,结果应该是
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"}]}]