2012-02-01 10 views
14

Jak mam usunąć tablicę kluczy w haszyszu? Na przykład, można zadzwonić:Usuń tablicę kluczy w Ruby Hash

hash_array.delete(some_key) 

Ale jak mogę to zrobić:

hash_array.delete([key1,key2,key3,...]) 

bez pętli w tablicy niepotrzebnie.

+0

Jeśli masz tablicę Pokochasz więc iterację niej w każdym przypadku. Może nie musisz przechowywać tych kluczy w tablicy, ale usuń je natychmiast. – megas

Odpowiedz

14

Można iteracyjne nad tablicę klawiszy i usunąć każdy z nich:

[key1, key2, key3].each { |k| some_hash.delete k } 

nie pamiętam żadnego lepszego rozwiązania.

+0

Staram się trzymać z daleka od pętli, ponieważ są one powolne, a ten kod jest zależny od czasu. –

+1

Rozumiem, ale jeśli masz do czynienia z tablicą kluczy, musisz mimo to iterować. Jakie są rozmiary haszu i tablicy w twoim przypadku? –

+0

Naprawdę nie potrzebuję iterować przez tablicę kluczy, wystarczy usunąć te klucze w haszyszu. Wartość mieszania ma około 20 000 elementów, ale musi się zapętlać wiele razy, a poszczególne elementy za każdym razem są różne. –

2

Może warto dokonać metoda

class Hash 
    def delete_by_keys *keys 
    keys.each{|k| delete(k)} 
    end 
end 

hash_array.delete_by_keys(key1,key2,..) 
+0

Może być przydatne. Dziękuję Ci. –

+1

'' 'keys.map'''' zamiast' '' keys.each''' zwraca tablicę wartości usuniętych. przydatny. – kuboon

10

Można spróbować użyć Hash#delete_if:

delete_if usuwa każdą parę klucz-wartość z HSH dla których blok wartość true.

array_hash.delete_if { |key, _| [key1, key2, key3].include? key } 

UPDATE Jeśli nie chcesz iteracyjne nad tablicę klawiszy, można użyć Set zamiast Array (od Set wykorzystuje Hash jako magazyn include? wynosi O (1)) :

require 'set' 
keys = [key1,key2,key3].to_set 
array_hash.delete_if { |key, _| keys.include? key } 
+0

+1. Chciałem to tylko dodać. Oczywiście iteruje również przez elementy (nawet kilka razy). –

+0

Jeśli rozmiar skrótu jest większy niż rozmiar tablicy, to podejście jest mniej wydajne niż iterowanie po tablicy. –

+1

@ KL-7, zgadzam się, zawsze jest wymagane, aby wykonać test porównawczy przed optymalizacją kodu, optymalizacja bez pomiaru może wydłużyć czas wykonania i zużycie pamięci. Nie zoptymalizowałbym takiego kodu. OP ma tylko kilka możliwości :) –

1

Można osiągnąć to, co zamierzają zrobić z operatorem "ikona" (*).

hash_array.delete *[key1,key2,key3,...] 

Jest to odpowiednik przekazywania każdego klucza jako oddzielnego argumentu.

+3

wygląda całkiem ładnie, ale nie działa. –

+1

też mnie nie obsługuje – traHfo

8

To jest dokładnie to, czego szukasz ... Możesz zrobić to w ten sposób bez niepotrzebnego przechodzenia przez tablicę.

keys_to_delete = [key1, key2, key3] 
hash_array.except!(*keys_to_delete) 

Wynik jest przechowywany w hash_array

+5

To jest część torów, a nie ruby. – sokkyoku