Ruby:同时循环两个哈希值,其中一个是嵌套哈希值

时间:2017-08-13 04:15:39

标签: ruby hash

我是编码和红宝石的新手,并为课堂作业。我们应该从优秀的出租车司机那里获取数据集,并找出每个司机获得的游乐设施数量和金额。我们可以以任何我们想要的方式自由构建代码。以下是我的代码。

我要做的是计算游乐设施的数量并将其存储在哈希rides_per_driver中。但是,使用if语句,我得到“没有将Array隐式转换为Integer(TypeError)”。如何让程序获取keys rides_per_driver并迭代哈希rides

感谢任何帮助。谢谢

# Stored rides data.
rides = {
  ride_1: {
    driver_id: "DR0004",
    date: "3rd Feb 2016",
    cost: 5,
    rider_id: "RD0022",
    rating: 5
  },

  ride_2: {
    driver_id: "DR0001",
    date: "3rd Feb 2016",
    cost: 10,
    rider_id: "RD0003",
    rating: 3
  },

 ride_3: {
    driver_id: "DR0002",
    date: "3rd Feb 2016",
    cost: 25,
    rider_id: "RD0073",
    rating: 5
  }
}



# iterate over the hash of hashes. If the driver id is x then
# add one ride to the tally.



# Storage for number of rides per driver
rides_per_driver = {
  "DR0001" => 0,
  "DR0002" => 0,
  "DR0003" => 0,
  "DR0004" => 0
}
amount_earned_per_driver = []

rides_per_driver.each do |x|
  if rides_per_driver.has_key?(rides_per_driver[x])
    rides.each do|ride_num, ride_data|
      rides.each do |k, v|
        rides_per_driver += 1
      end
    end
  else
    rides.each do|ride_num, ride_data|
      rides.each do |k, v|
        rides_per_driver = 1
      end
    end
  end


end

3 个答案:

答案 0 :(得分:1)

首先,让我们将您拥有的数据更改为两个驱动程序,其中一个"DR0004",有两个游乐设施:

rides = {
    ride_1: {
        driver_id: "DR0004",
        date: "3rd Feb 2016",
        cost: 5,
        rider_id: "RD0022",
        rating: 5
    },

    ride_2: {
        driver_id: "DR0004",
        date: "3rd Feb 2016",
        cost: 10,
        rider_id: "RD0003",
        rating: 3
    },

 ride_3: {
        driver_id: "DR0002",
        date: "3rd Feb 2016",
        cost: 25,
        rider_id: "RD0073",
        rating: 5
    }
}

您可以使用.group_by通过驱动程序获取驱动器驱动器的哈希值:

rides_by_driver=rides.group_by { |k, h| h[:driver_id] }
                     .map { |k, v| [k, v.to_h] }.to_h
{"DR0004"=>{:ride_1=>{:driver_id=>"DR0004", :date=>"3rd Feb 2016", :cost=>5, :rider_id=>"RD0022", :rating=>5}, :ride_2=>{:driver_id=>"DR0004", :date=>"3rd Feb 2016", :cost=>10, :rider_id=>"RD0003", :rating=>3}}, "DR0002"=>{:ride_3=>{:driver_id=>"DR0002", :date=>"3rd Feb 2016", :cost=>25, :rider_id=>"RD0073", :rating=>5}}}

然后你可以加上每个驱动程序的金额:

rides_by_driver.map { |k,v| [k, v.inject(0) { |sum,(k,v)| sum+=v[:cost] } ] }.to_h
{"DR0004"=>15, "DR0002"=>25}

或者,如果你想知道每个司机的游乐设施:

rides_by_driver.map { |k,v| [k, v.length] }.to_h
{"DR0004"=>2, "DR0002"=>1}

答案 1 :(得分:1)

rides = {
  ride_1: {
    driver_id: 'DR0004',
    date: '3rd Feb 2016',
    cost: 5,
    rider_id: 'RD0022',
    rating: 5
  },

  ride_2: {
    driver_id: 'DR0001',
    date: '3rd Feb 2016',
    cost: 10,
    rider_id: 'RD0003',
    rating: 3
  },

  ride_3: {
    driver_id: 'DR0002',
    date: '3rd Feb 2016',
    cost: 25,
    rider_id: 'RD0073',
    rating: 5
  }
}

# iterate over the hash of hashes. If the driver id is x then
# add one ride to the tally.

# Storage for number of rides per driver
rides_per_driver = {
  'DR0001' => 0,
  'DR0002' => 0,
  'DR0003' => 0,
  'DR0004' => 0
}
amount_earned_per_driver = []

我认为您需要做的就是让rides_per_driver更新

rides.each do |_key, val|
  rides_per_driver[val[:driver_id]] += 1
end

您遍历游乐设施并获得解决方案中rider_id的每个行程的val[:driver_id]。然后使用它来更新rides_per_driver中每个驱动程序的值。

答案 2 :(得分:1)

merge!

这使用Hash#update(aka _)的形式,它使用一个块来确定合并的两个哈希中存在的键的值。有关详细信息,请参阅文档,尤其是三个块变量(on和{{1}})的定义。 (我使用下划线代替公共密钥来表示密钥未在块计算中使用。)