从Hash ruby​​中获取值

时间:2013-04-19 22:17:44

标签: ruby ruby-on-rails-3 hash nokogiri

现在有点迷失了。我正在使用nokogiri从http://www.bbc.co.uk/sport/football/tables获取表格数据。我从SO那里得到了一些帮助,因为我不知道如何获取我想要的一些数据,我很慷慨地提供了一些他们会做的事情的例子

require 'open-uri'
require 'nokogiri'

url = 'http://www.bbc.co.uk/sport/football/tables'
doc = Nokogiri::HTML.parse(open url)
teams = doc.search('tbody tr.team')

keys = teams.first.search('td').map do |k|
  k['class'].gsub('-', '_').to_sym
end

hsh = teams.flat_map do |team|
  Hash[keys.zip(team.search('td').map(&:text))]
end

puts hsh

我对其中一些有点不清楚,我可以看到最终输出hsh给出了这个Hash例如

{:statistics=>"", :position=>"No movement 20", :team_name=>"Reading", :played=>"33", :home_won=>"4", :home_drawn=>"7", :home_lost=>"6", :home_for=>"23", :home_against=>"31", :away_won=>"1", :away_drawn=>"2", :away_lost=>"13", :away_for=>"13", :away_against=>"32", :goal_difference=>"-27", :points=>"24", :last_10_games=>"\n                                    Draw\nWin\nLoss\nLoss\nLoss\nLoss\nLoss\nLoss\nLoss\nDraw", :status=>"\n                    Report of Reading's last match                "}

{:statistics=>"", :position=>"No movement 19", :team_name=>"QPR", :played=>"33", :home_won=>"2", :home_drawn=>"8", :home_lost=>"6", :home_for=>"12", :home_against=>"23", :away_won=>"2", :away_drawn=>"4", :away_lost=>"11", :away_for=>"17", :away_against=>"31", :goal_difference=>"-25", :points=>"24", :last_10_games=>"\n                                    Draw\nDraw\nLoss\nLoss\nWin\nWin\nLoss\nLoss\nDraw\nLoss", :status=>"\n                    Report of QPR's last match                "}

所以我的想法就是抓住每一个:team_name我会经历一个像往常一样的循环

hsh.each do |k,v]
  v['team_name']
end

那么这会给我每个哈希值的team_name值吗?我想要实现的是Extracting elements with Nokogiri,但我想了解所提供的解决方案并将每个值保存到我的模型中

任何人都可以帮助澄清一些理解

由于

2 个答案:

答案 0 :(得分:3)

这实际上没有做任何有用的事情,它只会迭代hsh但不会执行任何操作,因为您想要的值将在k中:

hsh.each do |k,v]
  v['team_name']
end

问题是hsh实际上是一个哈希数组。保持相同的名称hsh,但将其视为数组:

hsh.map{ |a| a[:team_name]}

返回:

[
    [ 0] "Man Utd",
    [ 1] "Man City",
    [ 2] "Chelsea",
    [ 3] "Arsenal",
    [ 4] "Tottenham",
    [ 5] "Everton",
    [ 6] "Liverpool",
    [ 7] "West Brom",
    [ 8] "Swansea",
    [ 9] "Fulham",
    [10] "West Ham",
    [11] "Southampton",
    [12] "Newcastle",
    [13] "Norwich",
    [14] "Sunderland",
    [15] "Stoke",
    [16] "Aston Villa",
    [17] "Wigan",
    [18] "QPR",
    [19] "Reading"
]

如果我们只使用hsh查看hsh[0,2]中的前两个条目,可视化可能会更容易一些:

[15] (pry) main: 0> hsh[0,2]
[
    [0] {
             :statistics => "",
               :position => "No movement 1",
              :team_name => "Man Utd",
                 :played => "33",
               :home_won => "14",
             :home_drawn => "0",
              :home_lost => "2",
               :home_for => "40",
           :home_against => "17",
               :away_won => "12",
             :away_drawn => "3",
              :away_lost => "2",
               :away_for => "35",
           :away_against => "18",
        :goal_difference => "40",
                 :points => "81",
          :last_10_games => "\n                                    Win\nWin\nWin\nWin\nWin\nWin\nWin\nLoss\nWin\nDraw",
                 :status => "\n                    Report of Man Utd's last match                "
    },
    [1] {
             :statistics => "",
               :position => "No movement 2",
              :team_name => "Man City",
                 :played => "32",
               :home_won => "12",
             :home_drawn => "3",
              :home_lost => "1",
               :home_for => "36",
           :home_against => "11",
               :away_won => "8",
             :away_drawn => "5",
              :away_lost => "3",
               :away_for => "22",
           :away_against => "16",
        :goal_difference => "31",
                 :points => "68",
          :last_10_games => "\n                                    Win\nDraw\nDraw\nLoss\nWin\nWin\nLoss\nWin\nWin\nWin",
                 :status => "\n                    Report of Man City's last match                "
    }
]

  

我不完全理解我们如何获得返回的哈希

你得到了一系列哈希,因为:

  Hash[keys.zip(team.search('td').map(&:text))]

将一组键/值对强制转换为哈希。您有一系列键/值对,因为keys.zip(team.search('td').map(&:text))交织了keysteam.search('td').map(&:text)的结果。


  

所以要将每个团队名称保存到模型中,我现在可以循环遍历一个循环吗?

File.open('team_names.txt', 'w') do |fo|
  fo.puts hsh.map{ |a| a[:team_name] }
end

可能看起来需要hsh.map{ |a| a[:team_name] }.map(&:to_s),但puts会自动为返回数组中的每个元素执行to_s,将符号自动转换回字符串。< / p>


  

如果我想映射出team_name和position,那么我必须创建单独的调用,即每个值上的映射?我不能在同一个电话中映射多个值吗?

这将创建一个数组数组:

ary_of_arys = hsh.map{ |a| [ a[:team_name], a[:position] ] }

这将连接每一行的所有内部数组,然后打印出行:

File.open('team_names.txt', 'w') do |fo|
  fo.puts hsh.map{ |a| [ a[:team_name], a[:position] ].join(', ') }
end

答案 1 :(得分:2)

require 'open-uri'
require 'nokogiri'

url = 'http://www.bbc.co.uk/sport/football/tables'
doc = Nokogiri::HTML.parse(open url)
teams = doc.search('tbody tr.team')

keys = teams.first.search('td').map do |k|
  k['class'].gsub('-', '_').to_sym
end

hsh = teams.flat_map do |team|
  Hash[keys.zip(team.search('td').map(&:text))]
end
hsh.each do |x|
    p x[:team_name]
end

输出:

"Man Utd"
"Man City"
"Chelsea"
"Arsenal"
"Tottenham"
"Everton"
"Liverpool"
"West Brom"
"Swansea"
"Fulham"
"West Ham"
"Southampton"
"Newcastle"
"Norwich"
"Sunderland"
"Stoke"
"Aston Villa"
"Wigan"
"QPR"
"Reading"

修改

puts hsh

{:statistics=>"", :position=>"No movement 1", :team_name=>"Man Utd", :played=>"33", :home_won=>"14", :home_drawn=>"0", :home_lost=>"2", :home_for=>"40", :home_against=>"17", :away_won=>"12", :away_drawn=>"3", :away_lost=>"2", :away_for=>"35", :away_against=>"18", :goal_difference=>"40", :points=>"81", :last_10_games=>"\n                                    Win\nWin\nWin\nWin\nWin\nWin\nWin\nLoss\nWin\nDraw", :status=>"\n                    Report of Man Utd's last match                "}
{:statistics=>"", :position=>"No movement 2", :team_name=>"Man City", :played=>"32", :home_won=>"12", :home_drawn=>"3", :home_lost=>"1", :home_for=>"36", :home_against=>"11", :away_won=>"8", :away_drawn=>"5", :away_lost=>"3", :away_for=>"22", :away_against=>"16", :goal_difference=>"31", :points=>"68", :last_10_games=>"\n                                    Win\nDraw\nDraw\nLoss\nWin\nWin\nLoss\nWin\nWin\nWin", :status=>"\n                    Report of Man City's last match                "}
{:statistics=>"", :position=>"Moving up 3", :team_name=>"Chelsea", :played=>"32", :home_won=>"10", :home_drawn=>"4", :home_lost=>"2", :home_for=>"35", :home_against=>"13", :away_won=>"8", :away_drawn=>"3", :away_lost=>"5", :away_for=>"29", :away_against=>"20", :goal_difference=>"31", :points=>"61", :last_10_games=>"\n                                    Win\nDraw\nLoss\nWin\nLoss\nWin\nWin\nLoss\nWin\nWin", :status=>"\n                    Report of Chelsea's last match                "}
{:statistics=>"", :position=>"Moving down 4", :team_name=>"Arsenal", :played=>"33", :home_won=>"10", :home_drawn=>"4", :home_lost=>"3", :home_for=>"42", :home_against=>"21", :away_won=>"7", :away_drawn=>"5", :away_lost=>"4", :away_for=>"22", :away_against=>"14", :goal_difference=>"29", :points=>"60", :last_10_games=>"\n                                    Draw\nWin\nWin\nWin\nLoss\nWin\nWin\nWin\nWin\nDraw", :status=>"\n                    Report of Arsenal's last match                "}
{:statistics=>"", :position=>"No movement 5", :team_name=>"Tottenham", :played=>"32", :home_won=>"8", :home_drawn=>"5", :home_lost=>"3", :home_for=>"24", :home_against=>"17", :away_won=>"9", :away_drawn=>"2", :away_lost=>"5", :away_for=>"31", :away_against=>"23", :goal_difference=>"15", :points=>"58", :last_10_games=>"\n                                    Draw\nDraw\nWin\nWin\nWin\nWin\nLoss\nLoss\nWin\nDraw", :status=>"\n                    Report of Tottenham's last match                "}
{:statistics=>"", :position=>"No movement 6", :team_name=>"Everton", :played=>"33", :home_won=>"10", :home_drawn=>"6", :home_lost=>"1", :home_for=>"30", :home_against=>"17", :away_won=>"4", :away_drawn=>"8", :away_lost=>"4", :away_for=>"21", :away_against=>"20", :goal_difference=>"14", :points=>"56", :last_10_games=>"\n                                    Win\nDraw\nLoss\nLoss\nWin\nWin\nWin\nDraw\nWin\nDraw", :status=>"\n                    Report of Everton's last match                "}
{:statistics=>"", :position=>"No movement 7", :team_name=>"Liverpool", :played=>"33", :home_won=>"8", :home_drawn=>"4", :home_lost=>"4", :home_for=>"30", :home_against=>"14", :away_won=>"5", :away_drawn=>"7", :away_lost=>"5", :away_for=>"29", :away_against=>"26", :goal_difference=>"19", :points=>"50", :last_10_games=>"\n                                    Draw\nDraw\nLoss\nWin\nWin\nWin\nLoss\nWin\nDraw\nDraw", :status=>"\n                    Report of Liverpool's last match                "}
{:statistics=>"", :position=>"No movement 8", :team_name=>"West Brom", :played=>"32", :home_won=>"9", :home_drawn=>"2", :home_lost=>"5", :home_for=>"24", :home_against=>"16", :away_won=>"4", :away_drawn=>"3", :away_lost=>"9", :away_for=>"18", :away_against=>"27", :goal_difference=>"-1", :points=>"44", :last_10_games=>"\n                                    Draw\nLoss\nLoss\nWin\nWin\nLoss\nWin\nDraw\nLoss\nLoss", :status=>"\n                    Report of West Brom's last match                "}
{:statistics=>"", :position=>"No movement 9", :team_name=>"Swansea", :played=>"32", :home_won=>"6", :home_drawn=>"6", :home_lost=>"4", :home_for=>"28", :home_against=>"23", :away_won=>"4", :away_drawn=>"5", :away_lost=>"7", :away_for=>"15", :away_against=>"19", :goal_difference=>"1", :points=>"41", :last_10_games=>"\n                                    Win\nDraw\nLoss\nWin\nLoss\nWin\nLoss\nLoss\nLoss\nDraw", :status=>"\n                    Report of Swansea's last match                "}
{:statistics=>"", :position=>"No movement 10", :team_name=>"Fulham", :played=>"33", :home_won=>"7", :home_drawn=>"3", :home_lost=>"6", :home_for=>"25", :home_against=>"22", :away_won=>"3", :away_drawn=>"7", :away_lost=>"7", :away_for=>"19", :away_against=>"29", :goal_difference=>"-7", :points=>"40", :last_10_games=>"\n                                    Win\nLoss\nDraw\nWin\nDraw\nWin\nWin\nLoss\nDraw\nLoss", :status=>"\n                    Report of Fulham's last match                "}
{:statistics=>"", :position=>"Moving up 11", :team_name=>"West Ham", :played=>"33", :home_won=>"7", :home_drawn=>"5", :home_lost=>"4", :home_for=>"28", :home_against=>"20", :away_won=>"3", :away_drawn=>"4", :away_lost=>"10", :away_for=>"10", :away_against=>"27", :goal_difference=>"-9", :points=>"39", :last_10_games=>"\n                                    Loss\nWin\nLoss\nLoss\nWin\nLoss\nWin\nDraw\nDraw\nDraw", :status=>"\n                    Report of West Ham's last match                "}
{:statistics=>"", :position=>"Moving down 12", :team_name=>"Southampton", :played=>"33", :home_won=>"6", :home_drawn=>"6", :home_lost=>"5", :home_for=>"25", :home_against=>"20", :away_won=>"3", :away_drawn=>"5", :away_lost=>"8", :away_for=>"22", :away_against=>"34", :goal_difference=>"-7", :points=>"38", :last_10_games=>"\n                                    Loss\nDraw\nWin\nLoss\nLoss\nDraw\nWin\nWin\nWin\nDraw", :status=>"\n                    Report of Southampton's last match                "}
{:statistics=>"", :position=>"No movement 13", :team_name=>"Newcastle", :played=>"33", :home_won=>"9", :home_drawn=>"1", :home_lost=>"7", :home_for=>"24", :home_against=>"24", :away_won=>"1", :away_drawn=>"5", :away_lost=>"10", :away_for=>"18", :away_against=>"35", :goal_difference=>"-17", :points=>"36", :last_10_games=>"\n                                    Win\nWin\nLoss\nWin\nLoss\nWin\nLoss\nLoss\nWin\nLoss", :status=>"\n                    Report of Newcastle's last match                "}
{:statistics=>"", :position=>"No movement 14", :team_name=>"Norwich", :played=>"33", :home_won=>"6", :home_drawn=>"7", :home_lost=>"3", :home_for=>"18", :home_against=>"17", :away_won=>"1", :away_drawn=>"7", :away_lost=>"9", :away_for=>"13", :away_against=>"35", :goal_difference=>"-21", :points=>"35", :last_10_games=>"\n                                    Draw\nDraw\nDraw\nWin\nLoss\nDraw\nDraw\nLoss\nDraw\nLoss", :status=>"\n                    Report of Norwich's last match                "}
{:statistics=>"", :position=>"No movement 15", :team_name=>"Sunderland", :played=>"33", :home_won=>"4", :home_drawn=>"6", :home_lost=>"6", :home_for=>"17", :home_against=>"17", :away_won=>"4", :away_drawn=>"4", :away_lost=>"9", :away_for=>"20", :away_against=>"28", :goal_difference=>"-8", :points=>"34", :last_10_games=>"\n                                    Draw\nLoss\nLoss\nLoss\nDraw\nLoss\nDraw\nLoss\nLoss\nWin", :status=>"\n                    Report of Sunderland's last match                "}
{:statistics=>"", :position=>"No movement 16", :team_name=>"Stoke", :played=>"33", :home_won=>"6", :home_drawn=>"7", :home_lost=>"4", :home_for=>"19", :home_against=>"20", :away_won=>"1", :away_drawn=>"6", :away_lost=>"9", :away_for=>"9", :away_against=>"21", :goal_difference=>"-13", :points=>"34", :last_10_games=>"\n                                    Draw\nLoss\nWin\nLoss\nLoss\nLoss\nDraw\nLoss\nLoss\nLoss", :status=>"\n                    Report of Stoke's last match                "}
{:statistics=>"", :position=>"No movement 17", :team_name=>"Aston Villa", :played=>"33", :home_won=>"4", :home_drawn=>"5", :home_lost=>"8", :home_for=>"16", :home_against=>"25", :away_won=>"4", :away_drawn=>"5", :away_lost=>"7", :away_for=>"20", :away_against=>"35", :goal_difference=>"-24", :points=>"34", :last_10_games=>"\n                                    Loss\nDraw\nWin\nLoss\nLoss\nWin\nWin\nLoss\nWin\nDraw", :status=>"\n                    Report of Aston Villa's last match                "}
{:statistics=>"", :position=>"No movement 18", :team_name=>"Wigan", :played=>"32", :home_won=>"4", :home_drawn=>"4", :home_lost=>"8", :home_for=>"20", :home_against=>"32", :away_won=>"4", :away_drawn=>"3", :away_lost=>"9", :away_for=>"17", :away_against=>"26", :goal_difference=>"-21", :points=>"31", :last_10_games=>"\n                                    Loss\nDraw\nDraw\nLoss\nWin\nLoss\nWin\nWin\nDraw\nLoss", :status=>"\n                    Report of Wigan's last match                "}
{:statistics=>"", :position=>"No movement 19", :team_name=>"QPR", :played=>"33", :home_won=>"2", :home_drawn=>"8", :home_lost=>"6", :home_for=>"12", :home_against=>"23", :away_won=>"2", :away_drawn=>"4", :away_lost=>"11", :away_for=>"17", :away_against=>"31", :goal_difference=>"-25", :points=>"24", :last_10_games=>"\n                                    Draw\nDraw\nLoss\nLoss\nWin\nWin\nLoss\nLoss\nDraw\nLoss", :status=>"\n                    Report of QPR's last match                "}
{:statistics=>"", :position=>"No movement 20", :team_name=>"Reading", :played=>"33", :home_won=>"4", :home_drawn=>"7", :home_lost=>"6", :home_for=>"23", :home_against=>"31", :away_won=>"1", :away_drawn=>"2", :away_lost=>"13", :away_for=>"13", :away_against=>"32", :goal_difference=>"-27", :points=>"24", :last_10_games=>"\n                                    Draw\nWin\nLoss\nLoss\nLoss\nLoss\nLoss\nLoss\nLoss\nDraw", :status=>"\n                    Report of Reading's last match                "}