如果在另一个键/值对中找到相同的值,如何删除键/值对

时间:2017-06-09 16:48:10

标签: ruby-on-rails ruby

我创建了一个哈希并初始化了五个键/值对:

my_hash = {}
my_hash[:some_key]  = "hello world"
my_hash[:some_key2] = "apple"
my_hash[:some_key3] = "pear"
my_hash[:some_key4] = "hello world"
my_hash[:some_key5] = "pear"

> my_hash
  => {:some_key=>"hello world", :some_key2=>"apple", :some_key3=>"pear", :some_key4=>"hello world", :some_key5=>"pear"}

我希望每个键/值对的值都是唯一的。如果另一个键/值对具有匹配的value,则删除这些匹配的键/值对中的一个(我不关心最终删除哪个键/值对)。

因此,对于我的示例,我想删除这两个键/值对,因为已经有一个键/值对具有指定的value

my_hash[:some_key4] = "hello world"
my_hash[:some_key5] = "pear"

重申一下,可以删除其他匹配的键/值对。最终,每个键/值对的值必须是唯一的:

my_hash[:some_key]  = "hello world"
my_hash[:some_key3] = "pear"

返回的哈希值应为:

> my_hash
  => {:some_key=>"hello world", :some_key2=>"apple", :some_key3=>"pear"}

我该怎么做?我知道delete_if,但我不知道如何查看集合的其余部分,看看value是否存在于任何其他键/值对中。

5 个答案:

答案 0 :(得分:5)

您可以使用Array#uniq和转换到数组。

my_hash = {
  :some_key=>"hello world", 
  :some_key2=>"apple", 
  :some_key3=>"pear", 
  :some_key4=>"hello world", 
  :some_key5=>"pear",
}

my_hash.to_a # => [[:some_key, "hello world"], [:some_key2, "apple"], [:some_key3, "pear"], [:some_key4, "hello world"], [:some_key5, "pear"]]
my_hash.to_a.uniq(&:last) # => [[:some_key, "hello world"], [:some_key2, "apple"], [:some_key3, "pear"]]
my_hash.to_a.uniq(&:last).to_h # => {:some_key=>"hello world", :some_key2=>"apple", :some_key3=>"pear"}

答案 1 :(得分:4)

试试这个,或许:

my_hash.invert.invert

答案 2 :(得分:2)

不像大卫的答案那么简洁,但这将完成工作:

=IFERROR(INDEX(INDIRECT("C"&MATCH($F$1,C:C,0)+ROW()-ROW($1:$1)&":D999"),MATCH($F$1,INDIRECT("C"&MATCH($F$1,C:C,0)+ROW()-ROW($1:$1)&":C999"),0),2),"")

答案 3 :(得分:1)

类似于David Aldridge给出的答案,但会保留第一个具有值

的键
my_hash.reduce({}){|memo,(k,v)| memo[v] ||= k; memo}.invert

答案 4 :(得分:0)

正如我在这个问题的评论中所提到的那样:我问了这个问题,以便我以后可以将它应用到rails中的特定情况:当我调用@some_model.errors.messages时,我回到键/值对重复了价值或信息。我需要找到一种通过值获得唯一errors.messages的方法。这是一个奇怪的情况,我认为由于表格中的嵌套字段。

无论如何:这是解决方案,感谢其他答案的帮助:

@some_model.errors.messages.each do |attr, msg|
  @some_model.errors.delete(attr) if @some_model.errors.messages.values.flatten.find_all{|x| "#{[x]}" == "#{msg}"}.length > 1
end

有了这个,我知道错误哈希中的所有消息都是唯一的。