2011-04-08 17 views
6

Bir karma verilen perl işlevi map: kullanarak aşağıdaki eylemi yapmak için bir yol arıyorum, çiftleri (anahtar, değeri) değerin belirtilen bir parametreye eşit veya eşleştiği değer.eşleme hash değeri (anahtar, değer) eşleşen değer kümesi ayıklamak için kullanın

Örneğimde, value = failed'un (anahtar, değer) çiftlerini ayıklamak istiyorum, ancak aynı zamanda bir ifade de olabilir (örn. A ile başlayan bir dize veya bir REGEX). Bu yüzden bir sonuç olarak bir karma ve sadece değerlerle eşleşen anahtarların bir tablosunu istiyorum.

my %strings = (
    bla => "success", 
    ble => "failed", 
    bli => "failed", 
    foo => "success", 
    blo => "failed", 
    bar => "failed", 
    blu => "success" 
); 

my %failed_s =(); 

while (my ($k, $v) = each %strings) { 
    if ($v eq 'failed') {$failed_s{$k} = $v}; 
}; 

Bunu yapmanın birçok yolu denediklerini ama büyük sonuçlar yüzden ben vb

my %failed_s = 
    map { { $_ => $strings{$_} } 
    if ($strings{$_}./failed/) } 
    keys %strings; 
my %failed_s = 
    map { ($strings{$_} eq 'failed') && 
      ($_, $strings{$_}) } 
    keys %strings; 

print "Dumper \%failed_s: \n" . Dumper(\%failed_s); 

referanslar, özenti, sonuçları hakkında karıştı alıyorum düşünüyorum olmadan bu mümkün olmadığı ya da olabilir Bu durumda haritayı kullanmak etkili, fakat bana (ve muhtemelen başkalarının) nedenini bilmesine yardımcı olur.

+0

perl’in 'grep' – knittl

+0

@ knittl kullanmasını isterdim, ben de denedim ama nasıl çalıştığını gösteremedim eather, bununla ilgili bir örnek ya da fikrin varsa bunu görmekten memnun olurum! – Thomas

+1

@ @ mob's [answer] (http://stackoverflow.com/questions/5597542/using-map-to-extract-hash-set-of-key-value-matching-specified-value/5597656#5597656) 'ye bakın. –

cevap

6

İlk harita örneğinizde, tek öğe karma referanslarını döndürüyorsunuz, istediğiniz gibi değil.

İkincisinde, && işleci, argümanlarında skaler bağlam uygular, bu nedenle liste ($_, $strings{$_}) yalnızca listedeki son öğeyi döndürür.

Ne arıyorsun geçerli:

my %failed_s = map { 
    $strings{$_} eq 'failed' ? ($_, $strings{$_}) :() 
} keys %strings; 
koşul doğruysa ? : operatör listesini döndürür

ve boş liste eğer yanlış. LIST'deki her öğe üzerinde

+0

Boş liste, haritanın $ _'yi kendiliğinden% 'sini geçmesini engelleyen, verilerinizi atacak olan şeydir. –

3

map FUNC, LIST. İşleviniz bazı öğeler için boş bir liste verebilir (Eric Strom'un cevabı önerdiği gibi).

my %failed_s = map { 
    $_ => $strings{$_} 
} grep { $strings{$_} eq 'failed' } keys %strings; 
8

Perl birkaç kişi Anahtarı ayırt etmek mümkün olmuştur böyle bir ölçüde mantık karma kolay erişim gördü: map sadece ilgileniyorsunuz elemanları üzerinde işlem böylece başka bir yaklaşım Başka bir filtre kullanmaktır En yaygın uygulamasından -Veue Pair kavramı: Hash.

Çoğu Periler KVP'yi düşündüğünde, "karma" olduğunu düşünüyorlar. Ancak Perl Arrays'in 1) Listeler, 2) Kuyruklar ve 3) Yığınları düşünün ve uygulamanın konseptle tam olarak aynı olmadığını göreceksiniz. Ben zaten orada List::Pairwise bulana kadar

ben, ben CPAN yüklemek anlamına kendime bir kütüphane oluşturdu böylece sağlamalarının dışında bir tarzda çiftleri iyileştirmek için ihtiyaç gördü.

(benim "karma ekleme" yöntemlerine sahip görünmüyor Tabii ...) List::Pairwise kullanarak Neyse

, sadece

use List::Pairwise qw<grepp>; 
my %failed_s = grepp { $b eq 'failed' } %strings; 

Ben bir reklamla adam ne zaman gibi hissederdim Ben "Sadece ne kadar özlü bak!" Diyorum.

3

Sanırım bir harita + grep birleşik temizleyici.

my %failed_s = 
    map { $_ => $strings{$_} } 
    grep { $strings{$_} eq 'failed' } 
    keys(%strings); 

Ama grep haritası kullanılarak uygulanabilir beri

, sadece harita kullanarak yapılabilir

my %failed_s = 
    map { $_ => $strings{$_} } 
    map { $strings{$_} eq 'failed' ? $_ :() } 
    keys(%strings); 

.

my %failed_s = 
    map { $strings{$_} eq 'failed' ? ($_ => $strings{$_}) :() } 
    keys(%strings); 

Yapmış olduğunuz sorun, hiçbir şey vermemek istediğinizde yanlış döndüğünüzdür.

+0

teşekkürler, bu onu açıklığa kavuşturuyor! – Thomas

İlgili konular