迭代期间将键/值对添加到哈希时出现类型错误

问题描述 投票:0回答:3

我认为我误解了下面代码中的哈希值:

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 对象创建的每个哈希中。在循环中,我并没有尝试删除每个哈希的内容并仅用新的键/值对替换它,我有一种感觉我可能正在这样做。

如有任何帮助,我们将不胜感激。

ruby hash
3个回答
1
投票

由于您没有提供足够的信息,我们只能猜测,但最有可能的是,

story
是一个数组,而不是哈希。


1
投票

这会返回一个哈希数组,其中每个哈希都有键标题、类别和赞成票。

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()

0
投票

代码有几个问题,但导致错误的一个是

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}
]

更有用。

© www.soinside.com 2019 - 2024. All rights reserved.