Как найти ключ для конкретного значения массива из хэша с элементами массива? - PullRequest
0 голосов
/ 10 октября 2018

Каждое значение моего хэша является массивом:

tab_details = {
  'ex1' => ['1', '2']
}

Я хочу передать элемент и получить ключ, соответствующий массиву, в котором есть элемент.

Это одинспособ сделать это:

tab_details.each{|k, v|
  return key = k if tab_details[k].include? '1'
}

Есть ли другой оптимальный способ справиться с этим?

Ответы [ 5 ]

0 голосов
/ 10 октября 2018
hash.key(value) => key

В вашем случае

irb(main):012:0> tab_details.key(['1', '2']) => "ex1"

0 голосов
/ 10 октября 2018

Один (не очень прямой) способ сделать это может быть инвертировать Хэш , расширяющий каждый массив, чтобы сделать каждый элемент ключом:

tab_details = {
  'foo' => [2, 3, 5],
  'bar' => [1, 4, 6]
}
# => {"foo"=>[2, 3, 5], "bar"=>[1, 4, 6]}

inverted_hash = tab_details.each_with_object({}) do |(k, ary), out|
                  ary.each { |elem| out[elem] = k }
                end
# => {2=>"foo", 3=>"foo", 5=>"foo", 1=>"bar", 4=>"bar", 6=>"bar"}

input = 1
inverted_hash[input]
# => "bar"

Теперь, конечно, предполагается, что input и элементы массива имеют того же типа , то есть Integer.Вы можете конвертировать их в соотв.к тому, что дано в вашем вопросе:

# If all the array elements are strings
inverted_hash[input.to_s]
# => "bar"

Другое предположение, которое он делает, состоит в том, что нет элемента, присутствующего в более чем в одном массиве .

0 голосов
/ 10 октября 2018
tab_details.find { |_,v| v.include?("1") }&.first
  #=> "ex1"

tab_details.find { |_,v| v.include?("cat") }&.first
  #=> nil

& - оператор безопасной навигации .Во втором приведенном выше примере блок возвращает nil, поэтому из-за SNO first не выполняется и возвращается nil.

0 голосов
/ 10 октября 2018
> tab_details = {"ex1"=>["1", "2"], "ex2"=>["3", "4", "5"], "ex3"=>["2", "1", "9"]}
> tab_details.select{|k,v| v.include? "1"}.keys
#=> ["ex1", "ex3"]

для проверки целое число преобразование элементов массива в целое число с использованием map(&:to_i)

> tab_details.select{|k,v| v.map(&:to_i).include? 1}.keys
#=> ["ex1", "ex3"]

использование выбор , если один и тот же элемент может быть в нескольких массивах

0 голосов
/ 10 октября 2018

Вы можете использовать метод обнаружения

 k, v = tab_details.detect{ |_,v| v.include?("1") }

 p k
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...