2012-02-24 6 views
2

私の目標は、生スタックから良いキーリストにではありませんレコードを削除することです。Perlのハッシュをフィルタリングするために、より効率的な方法を探してい

これを最も効率的にどのように達成できますか?私が現在取り組んでいるコードはドラッグを感じています。私は提案のために開いています。

値がばかげて大きくなることがありますのでご注意ください。スタックキーコンテナを必要としないへの道がありますように私は感じ

foreach my $good_key (@good_keys) 
{ 
    foreach my $stack_key (@stack_keys) 
    { 
     my @stack = split(/~/, $stack_key); 
     if ($stack[1] eq $good_key) 
     { 

     } 
    } 
} 

# Main data container 
my %raw_stack = (
    'a1~a2~a3' => 'dat1~dat2', 
    'b1~b2~b3' => 'dat1~dat2', 
    'c1~c2~c3' => 'dat1~dat2', 
    'd1~d2~d3' => 'dat1~dat2', 
    'e1~e2~e3' => 'dat1~dat2', 
); 

# Container of stack keys only 
my @stack_keys = (
    'a1~a2~a3', 
    'b1~b2~b3', 
    'c1~c2~c3', 
    'd1~d2~d3', 
    'e1~e2~e3', 
); 

# Container of valid keys 
my @good_keys = (
    'a2', 
    'c2', 
    'e2', 
); 

は、ここで私が現在働いているコードです:

は、ここに私のデータです。私はちょっと...

+0

(1) '%stack_keys'は'%raw_stack'キーを使うだけでよいので、必要ありません。 (2)どのアプローチが最も効率的かは、これらの構造のサイズに依存する。 '@ good_keys'が小さければ、'%raw_stack'の各キーと照合できる単一の正規表現に変換するのが理にかなっていますが、大きければルックアップとして表現する方が意味がありますあなたが今のようにハッシュを行い、 'スプリット'を実行します。 – ruakh

答えて

8

そこにはfavorite quote by Larry Wallがあります: "連想配列で線形スキャンをするのは、ロードされたウジで誰かをクラブにしようとするようなものです。"

あなたは約hash slicesを知っておくべきです。あなたは以下のことを行うことができます。もちろん、それは正確なキーのリストを持っていることを意味します。しかし、説明します

my %clean_hash; 
@clean_hash{ @good_keys } = @raw_stack{ @good_keys }; 

をただし、あなたが値をコピーしたくない場合、あなたはもう少し複雑にこのような何かを行うことができます:

delete @raw_stack{ grep { $_ !~~ @good_keys } keys %raw_stack }; 

これは、5.10からsmart matchingを使用しています。

もちろん、それから適応する必要があります。中央のキー[1]だけを見ているとすれば、のパターンを探しているように見えるので、それを作成してください。

my $regex = join('|', sort { length($b) <=> length($a) or $a cmp $b } @good_keys); 
$regex = qr{~($regex)~}; 
delete @raw_stack{ grep { !m/$regex/ } keys %raw_stack }; 
+0

ありがとうございました。シンプルでエレガント:) – cr8ivecodesmith

+0

+1のための引用! – Dallaylaen

関連する問題