0

我可以创建一个哈希数组:

people = [
  {"Name" => "J.R. Kruger", "State" => "WA"},
  {"Name" => "Carl Hennings", "State" => "CA"}
]

然后我可以使用以下each语句:

people.each { |p| puts p["Name"] }

它将按照我的预期呈现一个名称列表。

"J.R. Kruger"
"Carl Hennings"

但是,如果我使用 JSON 对象的 Web 服务,这些对象会被解析为哈希数组:

speakers = JSON.parse(open("http://some.url.com/speakers.json").read)

它返回给我一个哈希数组。但是,如果我尝试做与上述代表人的哈希数组相同的事情:

speakers.each {|s| puts s["SpeakerName"]}

它只会输出扬声器的全部内容,这是一个哈希数组,而不是数组中"SpeakerName"每个哈希的键值的预期列表。

我应该补充一点,我可以做到:

speakers[0]["SpeakerName"] 

并获得所需的结果,以确保它不是错误的键。

缺少什么?


更新:

文件输出:

[
  {
    "Title"=>"Working with Maps in iOS 6: MapKit and CoreLocation in Depth",
    "Abstract"=>"Adding a Map to an App and recording a User\u2019s location as they use the App has become a common must have feature in may of todays popular applications. This presentation will go over the updated iOS 6 APIs for accomplishing such tasks including map annotations, dragging and dropping custom pins as well as delve into some of the finer aspects of the required location based calculations one needs to consider to find the center of the map or the distance between two points. Additionally the presentation will go over techniques to update a MapView with a moving object as well as positioning the image for the object properly along its heading. This will be a straight forward hands on development presentation with plenty of code examples.",
    "Start"=>"2013-01-11T20:35:00Z",
    "Room"=>"Salon A",
    "Difficulty"=>"Intermediate",
    "SpeakerName"=>"Geoffrey Goetz",
    "Technology"=>"Mac/iPhone",
    "URI"=>"/api/sessions.json/Working-with-Maps-in-iOS-6-MapKit-and-CoreLocation-in-Depth",
    "EventType"=>"Session",
    "Id"=>"4f248d87-0e18-488d-8cef-5e4130b8bb20",
    "SessionLookupId"=>"Working-with-Maps-in-iOS-6-MapKit-and-CoreLocation-in-Depth",
    "SpeakerURI"=>"/api/speakers.json/Geoffrey-Goetz"
  },
  {
    "Title"=>"Vendor Sessions - Friday",
    "Start"=>"2013-01-11T20:00:00Z",
    "End"=>"2013-01-11T20:20:00Z",
    "Room"=>"TBD",
    "Difficulty"=>"Beginner",
    "SpeakerName"=>"All Attendees",
    "Technology"=>"Other",
    "URI"=>"/api/sessions.json/Vendor-Sessions--Friday",
    "EventType"=>"Session",
    "Id"=>"43720cb8-d8ca-4694-8806-debcbdefa239",
    "SessionLookupId"=>"Vendor-Sessions--Friday",
    "SpeakerURI"=>"/api/speakers.json/All-Attendees"
  },
  {
    "Title"=>"Vendor Sessions - Thursday",
    "Start"=>"2013-01-10T20:00:00Z",
    "End"=>"2013-01-10T20:20:00Z",
    "Room"=>"TBD",
    "Difficulty"=>"Beginner",
    "SpeakerName"=>"All Attendees",
    "Technology"=>"Other",
    "URI"=>"/api/sessions.json/Vendor-Sessions--Thursday",
    "EventType"=>"Session",
    "Id"=>"2df202e4-219c-4efb-a838-3898d183dd19",
    "SessionLookupId"=>"Vendor-Sessions--Thursday",
    "SpeakerURI"=>"/api/speakers.json/All-Attendees"
  },
  {
    "Title"=>"Version your database on nearly any platform with Liquibase",
    "Abstract"=>"If you are still writing one-off scripts to manage your database, then it is time to make your life much simpler and less error-prone.  \nWe'll spend the time discussing Liquibase, a tool that will help you to manage that process.  It will even allow you to check your schema and seed data into source-control, and get new environments up and running quickly.  This session will focus not on the merits of using such a tool, but on its workflow and implementation in a project.  We'll run through the majority of features from the command-line, demonstrating that as long as a Java Runtime Environment (jre) is available, Liquibase can be used during deployments on any platform.  We'll also touch on usage with maven and quirks of Liquibase that are good to know ahead of time.",
    "Start"=>"2013-01-11T20:35:00Z",
    "Room"=>"Sagewood/Zebrawood",
    "Difficulty"=>"Beginner",
    "SpeakerName"=>"Daniel Bower",
    "Technology"=>"Continuous Deployment",
    "URI"=>"/api/sessions.json/Version-your-database-on-nearly-any-platform-with-Liquibase",
    "EventType"=>"Session",
    "Id"=>"4abb3869-bacd-42e1-93dc-14e712090b65",
    "SessionLookupId"=>"Version-your-database-on-nearly-any-platform-with-Liquibase",
    "SpeakerURI"=>"/api/speakers.json/Daniel-Bower"
  }
]
4

2 回答 2

1

我认为您正在使用 IRB 或 Pry 来查看您的数据和代码,这是正确的做法,但由于环境的行为方式,它也可能令人困惑。

我正在使用 Pry,如果我查看您的数组,并'SpeakerName'从每个哈希中提取字段,我会看到返回了四个:

[9] (pry) main: 0> ary.map{ |h| h['SpeakerName'] }
[
    [0] "Geoffrey Goetz",
    [1] "All Attendees",
    [2] "All Attendees",
    [3] "Daniel Bower"
]

如果我each再次使用并遍历数组,我会看到四个名称输出,然后是每个名称的返回值,然后 Pry 会显示该值。我在这里截断了它,因为它太长了。

[10] (pry) main: 0> ary.each{ |h| puts h['SpeakerName'] }
Geoffrey Goetz
All Attendees
All Attendees
Daniel Bower
[
[0] {
              "Title" => "Working with Maps in iOS 6: MapKit and CoreLocation in Depth",...

为了表明它是返回值,我通过附加;nil到该行来用不同的返回值欺骗 Pry:

[11] (pry) main: 0> ary.each{ |h| puts h['SpeakerName'] };nil
Geoffrey Goetz
All Attendees
All Attendees
Daniel Bower
nil

nil输出名称后,Pry 尽职尽责地返回。

此问题仅发生在 IRB 或 Pry 中,而不发生在正在运行的程序中。

于 2013-01-20T16:13:43.020 回答
0

答案实际上正是我在我的 OP 中建议的 -> 结果是 Array#each 返回数组。

因此,当在实例变量上调用 each 时,它会在 say(视图)中发布相同的结果,它会在执行块后返回整个数组。

有关源代码以及它如何返回作为最终返回结果的数组,请参阅Ruby Api 文档。

于 2013-01-20T22:01:40.540 回答