Ruby 如何反转散列,维护重复密钥

Ruby 如何反转散列,维护重复密钥,ruby,Ruby,从初始散列t: t = {"1"=>1, "2"=>2, "3"=>2, "6"=>3, "5"=>4, "4"=>1, "8"=>2, "9"=>2, "0"=>1, "7"=>1} >> h #=> {"1" => 1, "2" => 2, "2" => 3, "3" => 6, "4" => 5, "1" => 4, "2" => 8, "2" => 9, "1"

从初始散列
t

t = {"1"=>1, "2"=>2, "3"=>2, "6"=>3, "5"=>4, "4"=>1, "8"=>2, "9"=>2, "0"=>1, "7"=>1}
>> h
#=> {"1" => 1, "2" => 2, "2" => 3, "3" => 6, "4" => 5, "1" => 4, "2" => 8, "2" => 9, "1" => 0, "1" => 7} 
我需要按如下方式交换键和值:

t = {"1"=>1, "2"=>2, "3"=>2, "6"=>3, "5"=>4, "1"=>4, "8"=>2, "9"=>2, "1"=>0, "1"=>7}
同时保持散列的结构(即不折叠重复键)

然后我将用这个散列生成一个数组

有办法做到这一点吗?我试过这个:

t.find_all{ |key,value| value == 1 }   # pluck all elements with values of 1
#=> [["1", 1], ["4", 1], ["0", 1], ["7", 1]]
但是它返回一个新数组,并且初始哈希值没有改变

以下操作也不起作用:

t.invert.find_all{ |key,value| value == 1 }  
#=> []

以下是一种方法:

>> t = {"1" => 1, "2" => 2, "3" => 2, "6" => 3, "5" => 4, "4" => 1, "8" => 2, "9" => 2, "0" => 1, "7" => 1}
Hash#compare_by_identity
允许按值重复但按对象id唯一的键:

>> h = Hash.new.compare_by_identity
>> t.each_pair{ |k,v| h[v.to_s] = v.to_i }
t
的逆散列:

t = {"1"=>1, "2"=>2, "3"=>2, "6"=>3, "5"=>4, "4"=>1, "8"=>2, "9"=>2, "0"=>1, "7"=>1}
>> h
#=> {"1" => 1, "2" => 2, "2" => 3, "3" => 6, "4" => 5, "1" => 4, "2" => 8, "2" => 9, "1" => 0, "1" => 7} 
然后,您可以使用
find_all
检索元素数组,而无需修改
h

>> h.find_all{ |k,_|  k == "1" }
#=> [["1", 1], ["1", 1], ["1", 1], ["1", 1]]
>> h.keep_if{ |k,_|  k == "1"  }        
#=> {"1"=>1, "1"=>1, "1"=>1, "1"=>1}
>> h
#=> {"1"=>1, "1"=>1, "1"=>1, "1"=>1}
keep_if
返回变异的
h

>> h.find_all{ |k,_|  k == "1" }
#=> [["1", 1], ["1", 1], ["1", 1], ["1", 1]]
>> h.keep_if{ |k,_|  k == "1"  }        
#=> {"1"=>1, "1"=>1, "1"=>1, "1"=>1}
>> h
#=> {"1"=>1, "1"=>1, "1"=>1, "1"=>1}

请注意,此解决方案假定您希望在哈希中维护字符串键和整数值的模式。如果您需要整数键,
compare\u by\u identity
对您没有帮助。

哈希无效,您需要的哈希无效。哈希表中的多个元素的键不能只有一个值。您希望t[“1”]返回什么?如前所述,由于哈希表是按键索引的,因此您不可能需要它,这是一个一对一的映射,一个关键点到一个值。哈希表中不能实际存在两个相同的键。请注意,您发布的哈希表的文本表示形式与它在内存中的实际存在方式并不完全相同。@SirDarius(以及对任何支持SirDarius评论的人)不,您完全错了。哈希是一个映射,但不是一对一映射。许多键可以指向一个值。您与OP一样错误。即使您使用
compare_by_identity
,也无法切换键和值,因为假定的键是即时值。您悄悄地/秘密地将假定的键转换为字符串,将假定的值转换为数字。感谢您的帮助,您还想出了一个解决方案