Итерация по хешу с массивами в качестве значения - PullRequest
0 голосов
/ 08 января 2019

Я запрашиваю у пользователя ключ currentline и значение currentstation, чтобы сравнить его с хешем и показать, какую строку следует перемещать.

mtahash = {
  n: ["timesq", "34thn", "28thn", "23rdn", "Union_Square", "8th"],
  l: ["8th", "6th", "Union_Square", "3rd", "1st"],
  s: ["Grand Central", "33rds", "28th", "23rds", "Union Square", "Astor Place"]
}

puts "Please enter your current station"
current_station = gets.chomp
puts "Please enter your current line"
current_line = gets.chomp

mtahash.each do |key, value|
  if key == current_line && value == current_station
    puts "got it"
  else
    puts "fish"
  end
end

Мой код выводит fish три раза независимо от ввода.

Ответы [ 3 ]

0 голосов
/ 08 января 2019

each будет повторяться для каждого значения ключа (даже если найдено одно совпадение), но detect остановится, как только будет найдено совпадение.

Я думаю, что ключи для хэша уникальны, поэтому detect лучше, чем each

mtahash.detect { |k, v| k.to_s == current_line && v.include?(current_station) } ? 'got it' : 'fish'

Сокращение итераций.

 > mtahash = {:n=>["timesq", "34thn", "28thn", "23rdn", "Union_Square", "8th"], :l=>["8th", "6th", "Union_Square", "3rd", "1st"], :s=>["Grand Central", "33rds", "28th", "23rds", "Union Square", "Astor Place"]} 
 >   current_line, current_station = 'l', '3rd'
 => ["l", "3rd"] 

 > mtahash.detect { |k, v| k.to_s == current_line && v.include?(current_station) } ? 'got it' : 'fish'
 => "got it" 

 > current_line, current_station = 'l', '43rd'
 => ["l", "43rd"] 

 > mtahash.detect { |k, v| k.to_s == current_line && v.include?(current_station) } ? 'got it' : 'fish'
 => "fish" 
0 голосов
/ 08 января 2019

Я бы посоветовал преобразовать to_sym ( String # to_sym ), введенный пользователем для current_line, поскольку хеш-ключи являются символами.

Затем проверьте, есть ли у хэша этот ключ ( Hash # has_key ).

Наконец, получите доступ к хешу по ключу и проверьте, содержит ли массив ( Array # include ) current_station, поскольку значения хеша являются массивами.

Это просто фрагмент кода.

current_station = "timesq" # gets.chomp
current_line = "n".to_sym  # gets.chomp.to_sym <--- note .to_sym

if mtahash.has_key? current_line
    if mtahash[current_line].include? current_station
      then puts "got it"
      else puts "fish"
    end
  else puts "no line"
end


Более того, инвертируйте последовательность ввода, отметьте mtahash.has_key? после того, как пользователь введет строку, если true, перейдите к запросу станции.
0 голосов
/ 08 января 2019

A value в этой итерации является массивом. Вы должны проверить, включает ли оно название станции, а не равно ли оно ей. Также преобразуйте ключ в строку с помощью key.to_s (теперь это символ):

 mtahash.each do |key, value|
   if key.to_s == current_line && value.include?(current_station)
     puts "got it"
   else
     puts "fish"
   end
 end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...