从散列 table 中获取最小值并将其键分配给对象

Get the mininum value from a hash table and assign its key to an object

这是取自 this book 的一小段代码,关于 Ruby 中的 Dijkstra 算法:我想我不能 post 版权问题的整个例子,所以如果你需要可以从上面的link本书中下载源代码,该文件将在jwdsal2-code\code\connecting_everything_with_graphs\dijkstra.rb文件夹中。 - 它运行完美,代码中没有任何错误。

代码摘录如下:

    # We visit our next unvisited city. We choose the one that is cheapest
    # to get to from the STARTING city:
    current_city = unvisited_cities.min do |city|
      cheapest_prices_table[city.name]
    end

这是一个非常紧凑的结构,如果我完全理解它的意思的话:

我必须在不使用 min 的情况下实现它,这是我的尝试但没有成功,我认为问题是我错误地尝试将字符串分配给对象:

   min_cheapest_price = Float::INFINITY
   min_cheapest_city  = current_city.name
   unvisited_cities.each do |city|
      if cheapest_prices_table[city.name] < min_cheapest_price
         min_cheapest_price = cheapest_prices_table[city.name]
         min_cheapest_city = city.name         
      end
   end
   current_city = min_cheapest_city

那么,你有什么建议?非常感谢!

您的解决方案几乎是正确的。

您将城市的 name 分配给 current_city 变量,而原始解决方案分配城市对象。

min_cheapest_price = Float::INFINITY
min_cheapest_city  = nil # changed
unvisited_cities.each do |city|
  if cheapest_prices_table[city.name] < min_cheapest_price
    min_cheapest_price = cheapest_prices_table[city.name]
    min_cheapest_city = city # changed         
  end
end
current_city = min_cheapest_city

您可以进一步简化它并删除“中间”变量 min_current_city

min_cheapest_price = Float::INFINITY
current_city = nil
unvisited_cities.each do |city|
  if cheapest_prices_table[city.name] < min_cheapest_price
    min_cheapest_price = cheapest_prices_table[city.name]
    current_city = city         
  end
end

有时我会尽量避免像 Float::INFINITY 这样的“魔法”值,而只使用第一项来初始化

current_city = unvisited_cities.first
minimum_price = cheapest_prices_table[current_city.name] if current_city
unvisited_cities.each do |city|
  current_price = cheapest_prices_table[city.name]
  if current_price < minimum_price
    minimum_price = current_price
    current_city = city
  end
end

代码多一点(理论上更慢),当您从一开始就有真正的价值时,有时更容易调试。