我试图返回一个哈希数组,但只有最后一个哈希值被添加到数组中?

时间:2017-10-25 17:47:48

标签: ruby nokogiri

以下是我如何得到所有的手

def get_all_hands
  doc = Nokogiri::HTML(open('http://www.cardplayer.com/rules-of-poker/hand-rankings'))
  hand_hash = {}
  hands_array = []
  doc.css('div#rules-of-poker-accordion').each do |hands|
    hands.css('strong').each do |hand|
      hand_hash[:name] = hand.text
    end
    hands.css('div.rules-cards').each do |hand|
      hand_value = []
      hand.css('img').each do |card|
        hand_value << card.attr('src')
        hand_hash[:value] = hand_value
      end
    end
    hands_array << hand_hash
  end
  hands_array
end
HandScraper.new.get_all_hands

返回:

[{:name=>"10. High Card",
:value=>
["/packages/cards/Large/Diamond/3-909f8b1571f834c774576c93eae26594.png",
 "/packages/cards/Large/Club/J-58b4c0f26e3e0cf8c0772ab3e9e34784.png",
 "/packages/cards/Large/Spade/8-60d335b08119f600c3ca02aa58fa902d.png",
 "/packages/cards/Large/Heart/4-712ce04b7f2c7e588c48a1e2b46a4244.png",
 "/packages/cards/Large/Spade/2-e2d1cee5fc0db0b70990036153d57906.png"]}]

这是第十手也是最后一手,当我希望它返回所有10个时。

3 个答案:

答案 0 :(得分:3)

这段特殊代码是它不起作用的原因。您正在迭代每个strong将值分配给:name的相同密钥(hand_hash)。下一次迭代的情况也是如此。基本上,您将覆盖相同的哈希而不将其保存在任何位置,直到最后一次迭代。

hands.css('strong').each_with_index do |hand, index|
  hand_hash[index] = hand.text
end

我在您自己的代码中进行了一些更改以解决此问题:

doc = Nokogiri::HTML(open('http://www.cardplayer.com/rules-of-poker/hand-rankings'))
hands_array = []
doc.css('div#rules-of-poker-accordion').each do |hands|
  hands.css('strong').zip(hands.css('div.rules-cards')).each do |hand, value|
    hand_hash = {}
    hand_hash[:name] = hand.text
    hand_value = []
    value.css('img').each do |card|
      hand_value << card.attr('src')
      hand_hash[:value] = hand_value
    end
    hands_array << hand_hash #here, now you are saving after each hand
  end
end
hands_array

hands.css('strong').zip(hands.css('div.rules-cards'))会将每个名称规则配对,然后您只需将其添加到hands_array中。

结果:

  

[{:name =&gt;“1。皇家同花顺”,:值=&gt;
  [ “/packages/cards/Large/Diamond/A-49a04aae5e96d2f948dc2062c2c4fcd5.png”,       “/packages/cards/Large/Diamond/K-0bfc14d8f58cc13891b108e4178f92f9.png”       “/packages/cards/Large/Diamond/Q-b981aa1f57642480de1dceaf1c2e810f.png”       “/packages/cards/Large/Diamond/J-d915fc38dbca1ca74cdd75dd913de1f3.png”       “/packages/cards/Large/Diamond/T-ef2fe11bbd701e4c5b6681e506271700.png”]},   {:name =&gt;“2.直接冲洗”},{:name =&gt;“3。四种”,:value =&gt;   [ “/packages/cards/Large/Heart/J-2bf19067cda29391286416d0d00646d6.png”,       “/packages/cards/Large/Diamond/J-d915fc38dbca1ca74cdd75dd913de1f3.png”       “/packages/cards/Large/Spade/J-fff29c49da8ca1f7a272c5ac83f51d06.png”       “/packages/cards/Large/Club/J-58b4c0f26e3e0cf8c0772ab3e9e34784.png”       “/packages/cards/Large/Diamond/7-7e507c2122efe10ed7abacab95edff97.png”]},   {:name =&gt;“4. Full house”,:value =&gt;
  [ “/packages/cards/Large/Heart/T-c3f8fd4ffc3e09ec705a817aa212dc86.png”,       “/packages/cards/Large/Diamond/T-ef2fe11bbd701e4c5b6681e506271700.png”       “/packages/cards/Large/Spade/T-9a16f63a333b3edeb50c4372f8dd9883.png”       “/packages/cards/Large/Club/9-e6f0020a48aef9907b626477c5a60ac2.png”       “/packages/cards/Large/Diamond/9-3e500833bafc81a708d195f16d005125.png”]},   {:name =&gt;“5. Flush”,:value =&gt;
  [ “/packages/cards/Large/Spade/4-4200c8b5f3f5ba04d9fd5a69d71dab2f.png”,       “/packages/cards/Large/Spade/J-fff29c49da8ca1f7a272c5ac83f51d06.png”       “/packages/cards/Large/Spade/8-60d335b08119f600c3ca02aa58fa902d.png”       “/packages/cards/Large/Spade/2-e2d1cee5fc0db0b70990036153d57906.png”       “/packages/cards/Large/Spade/9-b0d71e77734375ceb3954156232f1f2d.png”]},   {:name =&gt;“6..Straight”,:value =&gt;
  [ “/packages/cards/Large/Club/9-e6f0020a48aef9907b626477c5a60ac2.png”,       “/packages/cards/Large/Diamond/8-6cd5b3025be0dd56cd52dfd2a49d922d.png”       “/packages/cards/Large/Spade/7-6c1d119e9c923f8e4773cf00d05e26d6.png”       “/packages/cards/Large/Diamond/6-a0c0218210a1a6c4ec17e5cec17ee3d8.png”       “/packages/cards/Large/Heart/5-f498916a3011c2b7199e1c1008dbe330.png”]},   {:name =&gt;“7.三种类型”,:value =&gt;
  [ “/packages/cards/Large/Club/7-5610625720208cc02c1107c91365eb37.png”,       “/packages/cards/Large/Diamond/7-7e507c2122efe10ed7abacab95edff97.png”       “/packages/cards/Large/Spade/7-6c1d119e9c923f8e4773cf00d05e26d6.png”       “/packages/cards/Large/Club/K-3e8312c33de4718943cd0276de8a16a1.png”       “/packages/cards/Large/Diamond/3-909f8b1571f834c774576c93eae26594.png”]},   {:name =&gt;“8.两对”,:value =&gt;
  [ “/packages/cards/Large/Club/4-33a9251d25da1ea2ba49e69e94549aee.png”,       “/packages/cards/Large/Spade/4-4200c8b5f3f5ba04d9fd5a69d71dab2f.png”       “/packages/cards/Large/Club/3-0c3eda54cfb6808b0a94950c045e497a.png”       “/packages/cards/Large/Diamond/3-909f8b1571f834c774576c93eae26594.png”       “/packages/cards/Large/Club/Q-9fcc4fd7692aa96ba9fcb04fa9fd727d.png”]},   {:name =&gt;“9.配对”,:value =&gt;
  [ “/packages/cards/Large/Heart/A-748f3f87f79ac475e6a432750725b64c.png”,       “/packages/cards/Large/Diamond/A-49a04aae5e96d2f948dc2062c2c4fcd5.png”       “/packages/cards/Large/Club/8-c3708e4821723f1100d514e5280b3f32.png”       “/packages/cards/Large/Spade/4-4200c8b5f3f5ba04d9fd5a69d71dab2f.png”       “/packages/cards/Large/Heart/7-1610ff3e74c68f6dd8a855bd16887457.png”]},   {:name =&gt;“10.高卡”,:value =&gt;
  [ “/packages/cards/Large/Diamond/3-909f8b1571f834c774576c93eae26594.png”,       “/packages/cards/Large/Club/J-58b4c0f26e3e0cf8c0772ab3e9e34784.png”       “/packages/cards/Large/Spade/8-60d335b08119f600c3ca02aa58fa902d.png”       “/packages/cards/Large/Heart/4-712ce04b7f2c7e588c48a1e2b46a4244.png”       “/packages/cards/Large/Spade/2-e2d1cee5fc0db0b70990036153d57906.png”]}]

希望有所帮助:)

答案 1 :(得分:0)

doc.css('div#rules-of-poker-accordion')调用返回一个div,因为这就是页面的结构。因此,您实际上只进入each循环一次。

该网站的布局有点滑稽,因此您必须分别获取名称和值。这是一个蛮力解决方案......

def get_all_hands
  doc = Nokogiri::HTML(open('http://www.cardplayer.com/rules-of-poker/hand-rankings'))
  hands_array = []

  doc.css('div#rules-of-poker-accordion').css("strong").each do |name|
    hands_array.push({name: name.text, value: []})
  end

  doc.css('div#rules-of-poker-accordion').css(".rules-cards").each_with_index do |hand, i|
    hand.css('img').each do |card|
      hands_array[i][:value].push card.attr('src')
    end
  end
  hands_array
end

答案 2 :(得分:0)

@kiddorails的答案是正确的,但你可以在这个问题上更简洁,更正常。考虑以下内容,它们给出相同的结果:

  def get_all_hands
    doc = Nokogiri::HTML(open('http://www.cardplayer.com/rules-of-poker/hand-rankings'))
    hands = doc.css('div#rules-of-poker-accordion').first
    hands.css('strong').zip(hands.css('div.rules-cards')).map do |hand, value|
      {name: hand.text, value: value.css('img').map { |card| card.attr('src') }}
    end
  end

Ruby拥有强大的方法来处理和转换数组。一旦你有了一个数组,就可以使用Ruby的一个富有表现力的Enumerable methods来转换它。 @kiddorails通过使用#zip将两个数组连接在一起开始这条路径,上面的重构通过获取生成的数组数组并使用#map将其转换为哈希数组来完成工作。

在Ruby中,只要你发现自己编写这种模式:

result = []
array.each { |element| result << method(element) }
result

您通常可以用以下内容替换这三行:

array.map { |element| method(element) }