2012-06-20 10 views
11

Yuvalanmış bir hash ile çalışıyorum.İç içe geçmiş bir hash'dan belirli bir öğeyi silme

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} 
} 

Amacım güverteden belirli bir kartı çıkarmak ve bu özel kart olmadan kart güverte iade edebilmek için şu şekildedir: Ben temsil bir deste kart var. Kimsenin karma yoluyla nasıl yineleneceği ve iki kulüp gibi bir kartın nasıl çıkarılacağı konusunda bana yardım edebilir mi?

deck_of_cards[:two][:clubs] 

Bu kod kartların bir takım kaldırmak için çalışır, ama belirli kart

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

Herhangi bir yardım takdir kaldırmak için ortaya çıkarması olamaz.

cevap

21

Sadece bu yapın:

deck_of_cards[:clubs].delete(:two) 
Buna olmadan deck_if_cards karma dönecektir de bu

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

gibi musluk işlevini kullanarak orijinal karma bir öğe kaldırmak ve dönebilirsiniz

+1

Yeni elemanı tamamen almak için herhangi bir yol var mı? Bu kod silinmiş öğeyi döndürdüğü için. – sidney

1

Bir karma içinde bir karma var, bu yüzden bunu yapabilirsiniz:

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

Sen iç üzerinde belirli bir değer silmek için anahtarları ve değerleri arasında yineleme ve bloğunun içinde bir koşul yapmak için each kullanmak karması.

+0

Underrated solution! –

+0

Subhash'a anahtar aracılığıyla erişebildiğinizde, neden karmayu yinelemelisiniz? – Bustikiller

0

Sen olurdu böyle bir şey olur:

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 

Böyle çiftler bir dizi olarak güverte temsil etmek daha iyi olabilir:

[ [:hearts, :two], [:hearts, :three], ... ] 

Sonra sadece gidebilir:

def remove_card deck, suit, number 
    deck.reject { |(s, n)| n == number and s == suit } 
end 
4

: iki anahtar da tek satırda yapabiliriz

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