Ruby times方法返回带有散列的nil

Ruby times方法返回带有散列的nil,ruby,random,hashmap,Ruby,Random,Hashmap,我所做的是从散列中随机获得2个值,并将它们与键匹配。我的代码得到两个随机值,这部分工作得很好。但是当涉及到p hash[m]时,我希望它会打印hash的键,而不是返回nil。例如: 我们的随机值是cat和ocean。程序使用时间方法自行拾取该值 所以当m=cat时,hash[m]应该是dog,但它是nil。海洋也是如此。所以我有两个零值。为什么?我怎样才能修好它并得到正确的钥匙 hash = { "foo" => "bar", "cat&q

我所做的是从散列中随机获得2个值,并将它们与键匹配。我的代码得到两个随机值,这部分工作得很好。但是当涉及到p hash[m]时,我希望它会打印hash的键,而不是返回nil。例如:

我们的随机值是cat和ocean。程序使用时间方法自行拾取该值

所以当m=cat时,hash[m]应该是dog,但它是nil。海洋也是如此。所以我有两个零值。为什么?我怎样才能修好它并得到正确的钥匙

hash = { "foo" => "bar", "cat" => "dog", "ear" => "nose", "ocean" => "sea"}
value = hash.values

2.times do 
  m = value[rand(value.size)]
  p hash[m] #Erroneous part
end

通过随机选择键来随机选择键/值对,因为这样更容易:

my_hash = { "foo" => "bar", "cat" => "dog", "ear" => "nose", "ocean" => "sea"}
my_keys = my_hash.keys

2.times do
  rand_key = my_keys[rand(my_keys.size)]
  rand_val = my_hash[rand_key]
  puts "#{rand_key} => #{rand_val}"
end

通过随机选择键来随机选择键/值对,因为这样更容易:

my_hash = { "foo" => "bar", "cat" => "dog", "ear" => "nose", "ocean" => "sea"}
my_keys = my_hash.keys

2.times do
  rand_key = my_keys[rand(my_keys.size)]
  rand_val = my_hash[rand_key]
  puts "#{rand_key} => #{rand_val}"
end

我的理解是,您得到了一个散列,希望随机选择两个值,然后标识与这些值关联的键。例如,如果

hash = { :a=>1, :b=>2, :c=>3 } 
这些值是

values = hash.values
  #=> [1, 2, 3]
在本例中,值是唯一的。稍后我将讨论值不唯一的一般情况,例如,{:a=>1,:b=>2,:c=>3,:d=>2}

如果随机选择两个值,我们将写入

random_values = values.sample(2)
  #=> [2, 1]
unique_values = values.uniq
  #=> [1, 2, 3]
random_values = unique_values.sample(2)
  #=> [3, 2]
在统计方面,样本见第3段。相比之下

random_values = 2.times.map { values[rand(values.size)] }
使用替换对两个值进行采样,因此随机_值可能相等,例如,[2,2]

获得随机_值后,假设[2,1]有两种方法获得相关密钥:

第一点如下

associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:b, :a]
尽管构造一个将键和随机值关联起来的散列可能更有用:

random_values.each_with_object({}) { |v,h| h[v] = hash.key(v) }
  #=> {2=>:b, 1=>:a}
看。第二种方法是使用:

然后我们简单地计算:

hsaH.values_at(*random_values)
  #=> [:b, :a]

见和

现在考虑值不唯一的一般情况。假设

hash = { :a=>1, :b=>2, :c=>3, :d=>2 }
其中:b和:d键具有相同的值

values = hash.values
  #=> [1, 2, 3, 2]
那么如果我们写

random_value = values.sample(2)
我们可以得到随机_值=>[2,2]。这可能是允许的,但如果需要两个唯一的值,我们将编写

random_values = values.sample(2)
  #=> [2, 1]
unique_values = values.uniq
  #=> [1, 2, 3]
random_values = unique_values.sample(2)
  #=> [3, 2]
是否使用值或唯一值取决于应用程序。不管怎样,如果结果是[3,2],使用上面的第一种方法,我们得到

keys = hash.keys
  #=> [:a, :b, :c, :d]
associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:c, :b] 
但是,这可能不令人满意,因为它取决于哈希键的顺序。假设:

hash = { :a=>1, :d=>2, :c=>3, :b=>2 }
在这种情况下,我们得到了不同的答案:

keys = hash.keys
  #=> [:a, :d, :c, :b]
associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:c, :d] 
同样地

{ :a=>1, :b=>2, :c=>3, :d=>2 }.invert
  #=> {1=>:a, 2=>:d, 3=>:c} 
{ :a=>1, :d=>2, :c=>3, :b=>2 }.invert
  #=> {1=>:a, 2=>:b, 3=>:c}
2的值不同

对于一般情况,根据应用程序,我们可以考虑编写以下内容:

hash = { :a=>1, :d=>2, :c=>3, :b=>2 }
values_to_keys = hash.each_with_object({}) do |(k,v),h|
  (h[v] ||= []) << k
end
  #=> {1=>[:a], 2=>[:d, :b], 3=>[:c]}
第二个例子:

random_values = values.sample(2)
  #=> [2, 2] 
random_values.map { |v| [v, values_to_keys[v].shift] }
  #=> [[2, :d], [2, :b]]

请注意,在计算值_到_键时,h[v]| |=[]我的理解是,给您一个散列,希望随机选择两个值,然后标识与这些值关联的键。例如,如果

hash = { :a=>1, :b=>2, :c=>3 } 
这些值是

values = hash.values
  #=> [1, 2, 3]
在本例中,值是唯一的。稍后我将讨论值不唯一的一般情况,例如,{:a=>1,:b=>2,:c=>3,:d=>2}

如果随机选择两个值,我们将写入

random_values = values.sample(2)
  #=> [2, 1]
unique_values = values.uniq
  #=> [1, 2, 3]
random_values = unique_values.sample(2)
  #=> [3, 2]
在统计方面,样本见第3段。相比之下

random_values = 2.times.map { values[rand(values.size)] }
使用替换对两个值进行采样,因此随机_值可能相等,例如,[2,2]

获得随机_值后,假设[2,1]有两种方法获得相关密钥:

第一点如下

associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:b, :a]
尽管构造一个将键和随机值关联起来的散列可能更有用:

random_values.each_with_object({}) { |v,h| h[v] = hash.key(v) }
  #=> {2=>:b, 1=>:a}
看。第二种方法是使用:

然后我们简单地计算:

hsaH.values_at(*random_values)
  #=> [:b, :a]

见和

现在考虑值不唯一的一般情况。假设

hash = { :a=>1, :b=>2, :c=>3, :d=>2 }
其中:b和:d键具有相同的值

values = hash.values
  #=> [1, 2, 3, 2]
那么如果我们写

random_value = values.sample(2)
我们可以得到随机_值=>[2,2]。这可能是允许的,但如果需要两个唯一的值,我们将编写

random_values = values.sample(2)
  #=> [2, 1]
unique_values = values.uniq
  #=> [1, 2, 3]
random_values = unique_values.sample(2)
  #=> [3, 2]
是否使用值或唯一值取决于应用程序。不管怎样,如果结果是[3,2],使用上面的第一种方法,我们得到

keys = hash.keys
  #=> [:a, :b, :c, :d]
associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:c, :b] 
但是,这可能不令人满意,因为它取决于哈希键的顺序。假设:

hash = { :a=>1, :d=>2, :c=>3, :b=>2 }
在这种情况下,我们得到了不同的答案:

keys = hash.keys
  #=> [:a, :d, :c, :b]
associated_keys = random_values.map { |v| hash.key(v) }
  #=> [:c, :d] 
同样地

{ :a=>1, :b=>2, :c=>3, :d=>2 }.invert
  #=> {1=>:a, 2=>:d, 3=>:c} 
{ :a=>1, :d=>2, :c=>3, :b=>2 }.invert
  #=> {1=>:a, 2=>:b, 3=>:c}
2的值不同

对于一般情况,根据应用程序,我们可以考虑编写以下内容:

hash = { :a=>1, :d=>2, :c=>3, :b=>2 }
values_to_keys = hash.each_with_object({}) do |(k,v),h|
  (h[v] ||= []) << k
end
  #=> {1=>[:a], 2=>[:d, :b], 3=>[:c]}
第二个例子:

random_values = values.sample(2)
  #=> [2, 2] 
random_values.map { |v| [v, values_to_keys[v].shift] }
  #=> [[2, :d], [2, :b]]

请注意,在计算值_到_keys时,h[v]| |=[]如果要按值搜索,请使用p hash.invert[m],否则如果要按键查找,请将value=hash.values更改为value=hash.keys要使p hash[m]起作用,m需要是键,而不是值。另外,通常情况下,您使用键而不是值访问哈希,因此将代码更改为按键选择,然后可以轻松地将值作为哈希[my_key]获取。如果要按值搜索,请使用p hash。反转[m]否则,如果要按键查找,请将value=hash.values更改为value=hash.keys要使p hash[m]起作用,m需要是键,而不是值。另外,通常,您使用键而不是值来访问散列,因此将代码更改为按键选择,然后您可以轻松地将值作为散列[my_key]来获取。