Ruby 从嵌套哈希中删除特定元素

Ruby 从嵌套哈希中删除特定元素,ruby,hash-of-hashes,Ruby,Hash Of Hashes,我正在尝试使用嵌套哈希。我有一副卡片,如下所示: deck_of_cards = { :hearts => {:two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, :ten => 10, :jack => 10, :queen => 10, :king =>

我正在尝试使用嵌套哈希。我有一副卡片,如下所示:

deck_of_cards = {
:hearts => {:two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, :ten => 10, :jack => 10, 
            :queen => 10, :king => 10, :ace => 11},
:spades => {:two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, :ten => 10, :jack => 10, 
            :queen => 10, :king => 10, :ace => 11},
:clubs => {:two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, :ten => 10, :jack => 10, 
            :queen => 10, :king => 10, :ace => 11},
:diamonds => {:two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, :ten => 10, :jack => 10, 
            :queen => 10, :king => 10, :ace => 11}
}
我的目标是能够从牌组中移除一张特定的牌,并返回没有该特定牌的牌组。有谁能帮我遍历散列并删除像两个俱乐部那样的卡片吗

deck_of_cards[:two][:clubs]
此代码用于删除一套卡,但我不知道如何删除特定的卡

deck_of_cards.delete_if {|k, v| k == :spades}

在散列中有一个散列,因此可以执行以下操作:

deck_of_cards.each {|k,v| v.delete(:two) if k == :clubs}

您可以使用
每个
迭代键和值,并在块内设置一个条件来删除内部哈希上的特定值。

您必须是这样的:

def remove_card deck, suit, number
  # do a deep clone
  new_deck = {}
  deck.each { |k, v| new_deck[k] = v.dup }

  # remove the card
  new_deck[suit] = new_deck[suit].reject { |k, v| k == number }

  new_deck
end
[ [:hearts, :two], [:hearts, :three], ... ]
最好将您的牌组表示为成对的数组,如下所示:

def remove_card deck, suit, number
  # do a deep clone
  new_deck = {}
  deck.each { |k, v| new_deck[k] = v.dup }

  # remove the card
  new_deck[suit] = new_deck[suit].reject { |k, v| k == number }

  new_deck
end
[ [:hearts, :two], [:hearts, :three], ... ]
然后你就可以走了:

def remove_card deck, suit, number
  deck.reject { |(s, n)| n == number and s == suit }
end
只要这样做:

deck_of_cards[:clubs].delete(:two)

您可以删除一个元素,也可以使用如下的tap函数返回原始散列

deck_of_cards.tap{|d| 
  d[:hearts].tap{|h| 
    h.delete(:two)
  }
}
如果卡片散列没有:两个键,则返回卡片组

你也可以在一行中完成

    deck_of_cards.tap{|d| d[:hearts].tap{|h| h.delete("two")}}
使用
。轻触


它的好处是以一种优雅的方式返回完整的散列,而不仅仅是已删除的值。

我认为这种方法可以为您完成这项工作

def nested_delete(card:, deck:)
  each do |hash_key, hash_value|
    if hash_key.to_s.eql?(deck)
      self[hash_key].delete(card.to_sym)
    end
  end
  self
end
假设你想从牌组“红心”中删除牌“六” 你需要做的就是

deck_of_cards.nested_delete(card: 'six', deck: 'hearts')

有没有办法完全检索新元素?因为此代码返回已删除的元素。低估的解决方案!当您可以通过键访问子哈希时,为什么要迭代哈希?我认为您的
“two”
应该是
:two
tap
在某些情况下肯定会有帮助,但您不需要嵌套它:
一副卡。tap{d}d[:hearts]。delete(:two)}