使用条件运算符“for”和Ruby的.each在哈希中打印值

问题描述 投票:2回答:2

我试图解决Ruby中一个非常简单的问题。我的目标是使用for循环和.each方法获取以下散列和打印值和键。

my_stocks = { 'Apple' => { 'symbol' => 'AAPL', 'price' => 100 },
          'Google' => { 'symbol' => 'GOOG', 'price' => 1150 },
          'Tesla' => { 'symbol' => 'TSLA', 'price' => 295 },
          'Microsoft' => { 'symbol' => 'MSFT', 'price' => 95},
          'Netflix' => { 'symbol' => 'NFLX', 'price' => 300},
          'Facebook' => { 'symbol' => 'FB', 'price' => 175},
          'Amazon' => { 'symbol' => 'AMZN', 'price' => 1250} }

所以,我正在使用这个定义的方法来打印整个哈希:

def execute_exercise(my_stocks)
for i, j in my_stocks
  puts j
end
end

显然,这成功了。我接下来要做的是,使用for循环只打印超过500的键的值。

我提出的每个解决方案都会在Ruby中引发错误:

rbtest.rb:18:in `>': no implicit conversion of Fixnum into Hash (TypeError)
from rbtest.rb:18:in `block in execute_exercise'
from rbtest.rb:18:in `each'
from rbtest.rb:18:in `execute_exercise'
from rbtest.rb:25:in `<main>'

我做的尝试是:

my_stocks.each {|symbol,price| puts symbol if price > 500}
for q, e in my_stocks.to_i < 500
      puts e
    end

我希望从哈希中打印出值,但很显然我在这里遗漏了一些东西。我不能在没有.to_h的情况下将fixnum转换为哈希,但这样做是否有效?我只是误解了循环还是别的什么?

ruby loops hash
2个回答
4
投票

你要求Ruby在这里做得太多了:

for q, e in my_stocks.to_i < 500

这真的没有任何意义。 for迭代一个容器。 to_i返回一个整数。 x.to_i < n返回一个布尔值。你不能迭代一个布尔值。另外,my_stocks是一个哈希,它没有做to_i,所以这整行不是Ruby可以理解的东西。

而是以不同的方式思考问题。 Ruby的方法是将其分解为几个步骤。首先,查找特定值以上的所有股票:

my_stocks.select do |_name, data|
  data['price'] > 500
end.each do |name, data|
  # ... print or whatever
end

这里采用Enumerable来帮助解决问题分两个阶段。 select过滤,each迭代。在Ruby中,for并没有真正使用,它真的不是最好的工具。

Enumerable的真正威力在于您可以将一个操作链接到下一个操作。对于不熟悉Ruby的人来说,end.each可能看起来很奇怪,但这确实是Ruby如何轻松处理复杂的操作。

例如,按价格(从最高到最低)进行过滤和排序只是一个小修改:

my_stocks.select do |_name, data|
  data['price'] > 500
end.sort_by do |_name, data|
  -data['price']
end.each do |name, data|
  # ... print or whatever
end

-data['price']部分是一种避免以后必须反转值的简单方法。通常它按递增顺序排序,因此当最高值变为最低值时,反转排序会逐渐减少。


0
投票

您可以像这样使用循环语法,但只需使用“next”跳过价格不符合您要求的项目的迭代:

for q, e in my_stocks
  next unless e['price'] > 500 
  puts q
  puts e
end

这将输出:

Google
{"symbol"=>"GOOG", "price"=>1150}
Amazon
{"symbol"=>"AMZN", "price"=>1250}
© www.soinside.com 2019 - 2024. All rights reserved.