我创建了一个哈希并初始化了五个键/值对:
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
是否存在于任何其他键/值对中。
答案 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
有了这个,我知道错误哈希中的所有消息都是唯一的。