Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如果在另一个键/值对中发现相同的值,如何删除键/值对_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 如果在另一个键/值对中发现相同的值,如何删除键/值对

Ruby on rails 如果在另一个键/值对中发现相同的值,如何删除键/值对,ruby-on-rails,ruby,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", :som

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

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"}
我希望每个键/值对的值都是唯一的。如果另一个键/值对具有匹配的
,则删除其中一个匹配的键/值对(我不在乎最终删除哪个键/值对)

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

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\u if
,但我不知道如何查看集合的其余部分,并查看
值是否存在于任何其他键/值对中。

试试这个,也许:

my_hash.invert.invert

虽然没有大卫的回答那么简洁,但这将完成工作:

my_hash.delete_if{|k,v| my_hash.values.find_all{|x| x == v}.length > 1}
您可以使用
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"}

与David Aldridge给出的答案类似,但将保留第一个具有该值的密钥

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

正如我在一篇关于这个问题的评论中提到的:我问这个问题是为了以后可以将它应用到rails中的一个特定情况:当我调用
@some_model.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

因此,我知道错误哈希中的所有消息都是唯一的。

您的键和值的顺序似乎不正确。值应该是键:)那么您的唯一性要求将根据hashmap的性质自动维护。@SergioTulentsev我相信我理解您的意思。这最终适用于rails的情况:
@model.errors.full\u消息
。在我的场景中,它返回一个带有此问题的哈希,因此我想删除键/值对,以便使它们在值上都是唯一的。我们希望看到您解决此问题的尝试。请参阅“”和Jon Skeet的“”。@当我在问题的最后一部分解释“我知道
delete_if
但我不知道如何浏览其余的收藏”时,很难显示我的尝试。我在这里解释说,我不知道如何在该集合上调用的方法块中迭代集合。这真的值得投反对票吗?理解堆栈溢出的目标很重要。这不是一个“给我一个问题的答案”网站,而是一个“这里有一个问题,以帮助他人在未来,连同相关的答案”网站。我们想帮助你,但你必须为将来帮助他们的人提供一个好问题。努力的证据(搜索和编码)排除了“给我密码”的问题,我们需要免费编码。我们希望你能在网站的目标上帮助我们,因为你在注册时同意这样做。这有助于解释吗
uniq_by
在ruby中实现为
Array#uniq
my_hash.to_a.uniq(&:last)。to_h=>{:some_key=>“hello world”、:some_key 2=>“apple”、:some_key 3=>“pear”}
@MickeySheu:啊,真的!我有关于其实现细节的过时信息:)虽然这个解决方案很聪明,但在实际的生产应用程序中,它不会通过我的代码审查。聪明往往是一种味道。如果我打算在生产系统中包含此内容,我肯定会将其作为一个有意义的名称进行细化,如
uniq_by_value
@Mark,请详细说明。@CarySwoveland因为它试图解决的问题并不明显,所以需要注释。任何需要解释的东西都是气味。David用一个有意义的名字来包装它的想法会有所帮助。@MarkThomas此外,逻辑的封装将允许根据元素的顺序对可能假设的任何副作用进行健壮的测试。您需要测试Ruby升级是否突然为您提供了last/first匹配键,而不是first/last(如果这对您很重要的话)