我认为我误解了下面代码中的哈希值:
require 'rest-client'
require 'json'
def get_from_mashable
res = JSON.load(RestClient.get('http://mashable.com/stories.json'))
res["hot"].map do |story|
s = {title: story["title"], category: story["channel"]}
add_upvotes(s)
end
end
def add_upvotes(hash)
hash.map do |story|
temp = {upvotes: 1}
if story[:category] == "Tech"
temp[:upvotes] *= 10
elsif story[:category] == "Business"
temp[:upvotes] *= 5
else
temp[:upvotes] *= 3
end
end
hash.each {|x| puts x}
end
get_from_mashable()
我从中得到以下错误:
ex_teddit_api_news.rb:16:in `[]': no implicit conversion of Symbol into Integer (TypeError)
我正在尝试将
upvotes
键和相应的整数值添加到从 get_from_mashable
中的 JSON 对象创建的每个哈希中。在循环中,我并没有尝试删除每个哈希的内容并仅用新的键/值对替换它,我有一种感觉我可能正在这样做。
如有任何帮助,我们将不胜感激。
由于您没有提供足够的信息,我们只能猜测,但最有可能的是,
story
是一个数组,而不是哈希。
这会返回一个哈希数组,其中每个哈希都有键标题、类别和赞成票。
require 'rest-client'
require 'json'
def get_from_mashable
res = JSON.load(RestClient.get('http://mashable.com/stories.json'))
res["hot"].map do |story|
s = {title: story["title"], category: story["channel"], upvotes: get_upvotes(story["channel"]) }
end
end
def get_upvotes(category)
case category
when "Tech"
10
when "Business"
5
else
3
end
end
get_from_mashable()
代码有几个问题,但导致错误的一个是
hash.map do |story|
正在逐一迭代单个哈希的键和值就好像它是[k,v,k,v…]
然后[some key]
的数组一样正在针对 story
(一个字符串)进行调用,并导致类型错误(String#[index]
是 Ruby 认为您想要调用的内容,因此抱怨无法将符号转换为整数)。
代码的意图意味着应该使用保存哈希值的数组,因此
story
应该保存哈希值。通过对代码进行一些细微的修改可以更容易地看到这一点:
def get_from_mashable
#res = JSON.load(RestClient.get('http://mashable.com/stories.json'))
res = {"hot" => [{"title" => "abc", "channel" => "xyz"}]}
res["hot"].map do |story|
s = {title: story["title"], category: story["channel"]}
add_upvotes(s)
end
end
def add_upvotes(hash)
p hash
#<snip!>
调用
get_from_mashable
将导致打印 {:title=>"abc", :category=>"xzy"}
。
如果我们然后通过
each
输出它,我们可以看到 map
要么是错误的方法选择(因为它在下面使用了 each
),要么选择了错误的对象类型来传递:
hash.each {|x| puts x }
# title
# abc
# category
# xzy
这意味着
hash.map do |story|
在其第一个循环中的 "title"
变量中有 story
,因此像 story[:category]
这样的调用将会失败并出现错误。
通过一些小的更改,代码应该执行看起来需要的操作:
def add_upvotes(story)
story[:upvotes] = 1
# No need for the map
if story[:category] == "Tech"
story[:upvotes] *= 10
elsif story[:category] == "Business"
story[:upvotes] *= 5
else
story[:upvotes] *= 3
end
story
end
def get_from_mashable
#res = JSON.load(RestClient.get('http://mashable.com/stories.json'))
# Stand in for the network call
res = {"hot" => [
{"title" => "techie stuff", "channel" => "Tech"},
{"title" => "biznass", "channel" => "Business"},
{"title" => "something else", "channel" => "xyz"},
]}
stories = res["hot"].map do |story|
s = {title: story["title"], category: story["channel"]}
add_upvotes(s)
end
stories
end
get_from_mashable()
哪个输出:
[
{:title=>"techie stuff", :category=>"Tech", :upvotes=>10},
{:title=>"biznass", :category=>"Business", :upvotes=>5},
{:title=>"something else", :category=>"xyz", :upvotes=>3}
]
更有用。