Удаление определенного элемента из вложенного хэша

Я пытаюсь работать с вложенным хешем. У меня есть колода карт, представленных следующим образом:

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}

Любая помощь приветствуется.

Ответ 1

Просто сделайте следующее:

deck_of_cards[:clubs].delete(:two)

Ответ 2

Вы можете удалить элемент и вернуть исходный хеш, используя функцию tap, например,

deck_of_cards.tap{|d| 
  d[:hearts].tap{|h| 
    h.delete(:two)
  }
}

это приведет к возврату хэша deck_if_cards без: два ключа

вы можете сделать это в одной строке также

    deck_of_cards.tap{|d| d[:hearts].tap{|h| h.delete("two")}}

Ответ 3

У вас есть хэш внутри хэша, поэтому вы можете сделать это:

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

Вы используете each для итерации по клавишам и значениям и создания условия внутри блока для удаления определенного значения во внутреннем хеше.

Ответ 4

Вам нужно будет что-то вроде этого:

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