2010-09-28 11 views
15

Chciałbym całkowicie zresetować mój %hash, tak aby nie zawierał żadnych klawiszy ani wartości. Wolę używać jednej linijki niż użyć pętli.Jak mogę całkowicie zresetować hash bez użycia pętli for?

Do tej pory próbowałem:

%hash = 0; 
%hash = undef; 

Ale to zarówno rzucać błędy w trybie ścisłym z ostrzeżeń włączone, więc napisałem prosty dla pętli osiągnąć to samo:

for (keys %hash) { 
    delete $hash{$_}; 
} 

ten działa, ale naprawdę chciałbym to zrobić z jednym linerem. Czy istnieje sposób, aby po prostu zresetować hash, który przeglądam?

+9

Jestem zdziwiony, że nikt nie ma już unasked pytanie. AFAICR Nigdy nie miałem potrzeby resetowania skrótu, ponieważ w Perlu można mieć naprawdę napięte zakresy. Zamiast tego pozwalam, by zmienne po prostu wypadały z zakresu; jeśli w pętli, nowy leksykalny zostanie utworzony z 'my' w górnej części. - Myślę, że jest to problem XY z miejscem na ulepszenie algorytmiczne, być może podać trochę więcej kontekstu? – daxim

+0

Hash to globalny, który tworzę w pobliżu początku mojego programu po wszystkich kontrolach i saldach. Jest modyfikowany różnymi podprogramami, dopóki nie przydzielę ostatecznej wersji do tablicy. Biorąc pod uwagę ten przepływ, chyba że czegoś brakuje, uważam, że łatwiej jest mi "zresetować" ten konkretny hash po przypisaniu go do tablicy, niż odtworzyć go za pomocą instrukcji "my". (Możliwe, że przeoczyłem problem XY, ponieważ nie wiedziałem, jak zrobić coś w stylu resetowania hash) – Structure

Odpowiedz

35

Oba modele: %hash =(); i undef %hash; będą działać, z tą różnicą, że te ostatnie zwrócą trochę pamięci do użycia dla innych rzeczy. Ten pierwszy zachowa wspomnienia w haszymdzie używanym wcześniej, zakładając, że i tak będzie użyty później, kiedy hasz zostanie uzupełniony.

Można użyć Devel::Peek zauważyć, że zachowanie:

$ perl -MDevel::Peek -we'my %foo = (0 .. 99); %foo =(); Dump \%foo; undef %foo; Dump \%foo' 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x23b5d38 
    KEYS = 0 
    FILL = 0 
    MAX = 63 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

W MAX pola w PVHV s są ważne bit.

+0

Dzięki za dodatkowy wgląd. Spodziewam się, że mój hash nigdy nie będzie zawierał tych samych wartości, gdy zostanie ponownie wypełniony, więc wykorzystam undef% hash; składnia. – Structure

+11

Nie chodzi o to, jakie wartości są przechowywane w haśle, ale o to, ile z nich istnieje.Przydzielanie, zwalnianie, a następnie przydzielanie pamięci w celu przechowywania wartości w haszach nie jest najszybszą rzeczą, jaką możesz zrobić, więc perl przyjmuje założenie, że hasz ostatecznie wzrośnie do pierwotnego rozmiaru, nawet jeśli zostanie wyczyszczone za pomocą '' % h =() 'i zachowuje pamięć wymaganą do przechowywania wielu elementów w haszdzie, chyba że wyraźnie poproszono, aby tego nie robić. Nie należy tego mylić z pamięcią, której zajmują twoje rzeczywiste wartości w haszy. – rafl

+0

Teraz widzę różnicę. W porządku, będę musiał użyć Devel :: Peek, aby zobaczyć, który jest bardziej wydajny w moim przypadku użycia. – Structure

2

Zastosowanie

%hash =(); 
+2

Z 'my' tam, w rzeczywistości tworzysz nowy skrót niezwiązany z istniejącym, nie usuwając stary hasz. – cjm

+0

jest teraz poprawione – Thariama

0

Ponieważ PO poprosił o jedną wkładką, która działa przy użyciu ścisłe i ostrzeżeń

delete $hash{$_} for (keys %hash) 
Powiązane problemy