Как получить значения из хэша, если я знаю ключи другого хэша - PullRequest
1 голос
/ 26 апреля 2019

Я застрял на проблеме, когда у меня есть метод экземпляра и хеш, и я хочу использовать атрибуты метода для итерации по этому хешу для получения значения. Например, у меня есть метод:

class M
  def initialize(time, line)
    @time = YAML.load_file(time)
    @line = YAML.load_file(line)
  end

  def sum(from_station:, to_station:)
    array = @time['timing'] 
    lines = @line['lines']          
    line = @line['stations'] 
    from_station_line = line[from_station.to_s]
    to_station_line = line[to_station.to_s]
    str = from_station
    stop = to_station
    result = []
    result2 = []
    result3 = []
    time = 0
    if from_station_line[0] == to_station_line[0]
      loop do
      tmp = array.find{|x| x['start'] == str}
      break unless tmp
      result << tmp
      str = tmp['end']
      time = result.sum{|b| b['time']}
      break if str == stop
      end
      puts time
    else
      case array
    end
    p time, result2
   end
  end
end

a = M.new("./config/time.yml", "./config/config.yml")
a.sum(from_station: :tokyo, to_station: :milan)

и станции config.yml:

lines:
  - :black
  - :red
  - :yellow
stations:
  tokyo:
    - :black
  chicago:
    - :black
  amster:
    - :black
    - :red
  prague:
    - :black
  milan:
    - :black
    - :red
  bayern:
    - :black
    - :yellow

А вот и time.yml

 timing:
  -
    start: :tokyo
    end: :chicago
    time: 6
    price: 3
  -
    start: :chicago
    end: :amster
    time: 4
    price: 2
  -
    start: :amster
    end: :prague
    time: 3.5
    price: 3
  -
    start: :bayern
    end: :milan
    time: 3.5
    price: 3
  -
    start: :milan
    end: :roma
    time: 3.5
    price: 3
  -

И мне нужно выбрать, если from_station: и to_station: на одной ветви (черный или красный или оба). Могу ли я сделать это? Другими словами: если пользователь решит перейти от станции ": Токио" к станции ": Милан", мне нужно знать, находятся ли эти две станции на одной линии (: черная, красная или желтая). Итак, чтобы знать, что мне нужно управлять файлом config.yml и выполнять итерации, если строка ": tokyo" [black] == строка ": milan [yellow]

1 Ответ

0 голосов
/ 26 апреля 2019

Обычно в Ruby вы не будете использовать операторы loop и break. Модуль Enumerable сделает большую часть этого за вас. Это может занять некоторое время, чтобы привыкнуть к нему, но тогда это станет естественным и позволит вам быстро ко многим вещам. Обратите внимание, что другие языки программирования используют аналогичные понятия.

В

  a = line.select {|k,v| k.to_sym == from_station}  #how to implement this condition?
  b = line.select {|k,v| k.to_sym == to_station}#

вы выполняете типичные поиски в Hash, что можно сделать с помощью

def sum(from_station, to_station)
  from_station_colors = @lines[from_station]
  to_station_colors   = @lines[to_station]

  if (from_station_colors.nil? || from_station_colors.empty?)
    # from_station not found
  end
  # ...
end

Поиск в timing немного сложнее:

require 'yaml'

timings = YAML::load_file('timing.yml')['timing']

from_station = :tokyo
to_station = :chicago

# "t" (a timing entry) might be nil, thus the first select
# Note that there are other handy functions to make this more readable
# (left as an exercise)
transit = timings.select{|t| t}.select do |timing|
  # if the following line evaluates to "true", select this entry
  timing['start'] == from_station && timing['end'] == to_station
end

puts transit # {"start"=>:tokyo, "end"=>:chicago, "time"=>6, "price"=>3}

Ваш другой вопрос (выясните, имеют ли места одинаковый «цвет»), вероятно, следует задавать отдельно. Почему-то эта задача звучит как домашнее задание.

И добро пожаловать в StackOverflow! Пожалуйста, постарайтесь как можно точнее ответить на ваш следующий вопрос (вопросы), сводя при этом примеры к «хорошему» минимуму.

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