我正在尝试使用嵌套哈希。我有一副卡片如下:
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}
答案 0 :(得分:26)
这样做:
deck_of_cards[:clubs].delete(:two)
答案 1 :(得分:7)
你可以删除元素并使用像这样的点击函数返回原始哈希
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")}}
答案 2 :(得分:1)
哈希中有哈希,所以你可以这样做:
deck_of_cards.each {|k,v| v.delete(:two) if k == :clubs}
使用each
迭代键和值,并在块内部创建条件以删除内部哈希上的特定值。
答案 3 :(得分:1)
.tap
deck_of_cards.tap{ |deck_of_cards| deck_of_cards[:hearts].delete(:two) }
#=> {
# :hearts=>{: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}
# }
具有以优雅的方式返回完整哈希而不仅仅是删除值的好处。
答案 4 :(得分:0)
你必须是这样的:
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
答案 5 :(得分:0)
我认为这种方法将为您完成工作
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')
答案 6 :(得分:0)
我确实在我的应用程序中编写了这个问题作为初始化程序,以向 Hash 对象添加一个名为 delete_nested_key
的方法。它删除哈希的嵌套键。您必须将 key_path 作为数组传递(只是要遍历的键列表以转到要删除的键)。
它似乎工作正常,但我刚刚写了它,所以它可能有问题。
class Hash
module NestedKeyDeletion
extend ActiveSupport::Concern
included do
def deleted_nested_key!(key_path)
nested_hash = fetch_most_inner_hash(key_path)
nested_hash.delete(key_path.last)
self
end
private
def fetch_most_inner_hash(key_path)
nested_hash = self
key_path.each_with_index do |key, index|
return nested_hash if index == key_path.size - 1
nested_hash = nested_hash.fetch(key)
end
end
end
end
end
Hash.include(Hash::NestedKeyDeletion)
然后你可以这样使用它:
[1] pry(main)> x = { x: { y: 2} }
=> {:x=>{:y=>2}}
[2] pry(main)> x.deleted_nested_key!([:x, :y])
=> {:x=>{}}
[3] pry(main)>
最好的问候, 丹尼尔。