user9409769
user9409769

Reputation:

How to iterate through nested array/hash and retrieve data from there

I stacked with a problem - solving a task where I have .yml file like this:

time:
  -
    begin: :washington
    end: :briston
    min: 6
    price: 3
  -
    begin: :briston
    end: :dallas
    min: 4
    price: 2
  -
    begin: :dallas
    end: :tokyo
    min: 3.5
    price: 3
  -
    begin: :tokyo
    end: :chicago
    min: 3.5
    price: 3

and a class Train, where I want to loop through this .yml file and extract neccessary information and operate with these values(start station, end station, price and duration).

class Train 
  require 'yaml'

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

  def calc(begin, end)
    @time.select do |key, value|
      puts key, value
    end
  end
end

In 'calc' method I defined 'select' method to retrieve keys and values, but it just printing all hash like this:

time
{"begin"=>:washington, "end"=>:briston, "min"=>6, "price"=>3}
{"begin"=>:briston, "end"=>:dallas, "min"=>4, "price"=>2}
{"begin"=>:dallas, "end"=>:tokyo, "min"=>3.5, "price"=>3}

How could I loop through this hash to extact neccessary data? Thanks in advance!

Upvotes: 0

Views: 53

Answers (1)

iGian
iGian

Reputation: 11183

If I get the point, see my comment, given the variable @time:

@time = {"time"=>[{"begin"=>:washington, "end"=>:briston, "min"=>6, "price"=>3}, {"begin"=>:briston, "end"=>:dallas, "min"=>4, "price"=>2}, {"begin"=>:dallas, "end"=>:tokyo, "min"=>3.5, "price"=>3}, {"begin"=>:tokyo, "end"=>:chicago, "min"=>3.5, "price"=>3}]}

One way to chain, to be refactored:

ary = @time['time']
start = :washington
stop = :tokyo
res = []
loop do
  tmp = ary.find { |h| h['begin'] == start }
  break unless tmp
  res << tmp
  start = tmp['end']
  break if start == stop
end

Then you have res:

#=> [{"begin"=>:washington, "end"=>:briston, "min"=>6, "price"=>3}, {"begin"=>:briston, "end"=>:dallas, "min"=>4, "price"=>2}, {"begin"=>:dallas, "end"=>:tokyo, "min"=>3.5, "price"=>3}]

To get for example the sum of min:

res.sum { |h| h['min'] } #=> 13.5

Upvotes: 1

Related Questions