2012-01-12 81 views
3

這是一個過度設計的解決方案,我認爲可以做得更好。基本上,它需要一個鍵數組來創建一個過濾器字符串,該過濾器字符串會根據哈希中的每個鍵進行檢查,以查看該鍵是否在過濾器字符串中包含索引...排除標誌將基於_filter的結果。可能不是最好的方法。有更好的方法嗎?如何快速過濾給定一組鍵的散列?

sub _filter{ 
    my ($filter,$key,$joiner) = @_; 
    $joiner = $joiner ? $joiner : '+'; 
    my $i = index($filter,$key); 
    if($i >= 0){ 
     my $c; 
     $c = substr($filter, $i-1, 1); 

     print STDERR "\nc => $c [$key][$i]"; 

     if($i==0){ return 1; } 
     return($c eq $joiner); 
    } 
    return 0; 
    } 

    sub hashFilter{ 
    my($hash,$filter_keys,$exclude) = @_; 
    return 0 unless isHash($hash) && $filter_keys; 

    $exclude = $exclude ? $exclude : 0; 
    my $filter = isArray($filter_keys)? join('+',@$filter_keys) : $filter_keys; 
    print STDERR "FILTER is > $filter"; 

    my $p = {map { (_filter($filter,$_) == $exclude) ? ($_ => $$hash{$_}) :() } keys %$hash}; 

    return $p; 
    } 

#isArray() and isHash() just check the ref value for "ARRAY" or "HASH" respectively 

...使用沒有額外模塊的標準perl! =]

這裏有些想法嗎?

使用映射和索引...這些fast-ish方法vs做正則表達式,還是有更好的函數使用?

回答

7

散片,有人嗎? :

my %filtered_hash; 
@filtered_keys = grep { exists $hash{$_} } @filtered_keys; 
@filtered_hash{@filtered_keys} = @hash{@filtered_keys}; 
+1

這會將'undef's添加到原始哈希中不存在的鍵的過濾哈希中,但是您可以通過使用'@filtered_keys = grep exists $ hash {$ _},@filtered_keys預處理鍵列表來解決此問題;'。 – 2012-01-14 15:15:05

+0

@IlmariKaronen:謝謝你指出。 – Zaid 2012-01-14 15:21:13

+0

zomg!^_ ^沒有人告訴我有關哈希片的聲音 – qodeninja 2012-01-14 19:33:25

11
 
my %filtered_hash = map { $_ => $hash{$_} } grep { exists $hash{$_} } @filter_keys; 
+3

或者將map和grep放在一起'map {exists $ hash {$ _}? ($ _ => $ hash {$ _}):()} @ filter_keys' – 2012-01-12 21:50:49

+0

@EricStrom這正是我想要的!簡短而甜美。 – ipetrik 2017-08-30 21:45:49

相關問題