2011-02-04 17 views
3

複雑なデータ構造を初めて使用しています。私はそれらの背後にあるアイデアを理解していますが、データを取得するのが難しいです。私は、私は何を必要していますが(「この場合は「4」)フィルタ名を与えられていることを確認しているPerl:複雑なデータ構造の要素を計算する

$VAR1 = { 
     '4' => { 
       'engine_coded' => 0, 
       'name' => 'FILTER_1', 
       'filter_actions' => { 
            'X_Override_Queue_Level' => 'Value' 
            }, 
       'filter_criteria' => [ 
             [ 
             'X_Charge', 
             '=', 
             'X_CHARGE_1' 
             ] 
            ] 
      } 
    }; 

....データ:: Dumperのを使用して、私の現在の問題の子の構造を発見しました「名前」は「filter_actions」と「filter_criteriaを」値を持っている、など。

誰もが最高これを実現する方法のアイデアを持っている?多くの感謝! Janie

+0

をそうよう

要素を数えますか? – Ether

答えて

5

構造を検証する関数を作成し、

まず...の部分にこれを打破するのをしてみましょう:

sub validate 
{ 
    my ($data) = @_; 

    # always return true for now 
    return 1; 
} 

今、あなたは、フィルタを使用したい...のはビットで埋め始めましょう妥当性チェックの一環として名前、それでは、引数としてそのを追加してみましょう。

sub validate 
{ 
    my ($data, $filter_name) = @_; 

    # always return true for now 
    return 1; 
} 

何かを行う前に、それはそのフィルタ名をキーとして存在しているかどうかをチェックするために理にかなって。一致しない場合は、検証に失敗しました:

sub validate 
{ 
    my ($data, $filter_name) = @_; 

    return if not exists $data->{$filter_name}; 

    # otherwise, return true 
    return 1; 
} 

また、値があることを確認してください。ハッシュ・キーの定義は 'exists'のスーパーセットであるため(定義されている値も存在する必要がありますが、存在するすべての値を定義する必要はありません - undefは値になります)、

sub validate 
{ 
    my ($data, $filter_name) = @_; 

    return if not defined $data->{$filter_name}; 

    # otherwise, return true 
    return 1; 
} 

我々はFILTER_NAMEキーがデータ内に存在していることをチェックしましたし、それが定義されていますが、より深い1つのレベルを探す前に、我々はそれが本当にハッシュ・リファレンスであることを確認する必要があります。今すぐ

sub validate 
{ 
    my ($data, $filter_name) = @_; 

    return if not defined $data->{$filter_name}; 

    return if ref $data->{$filter_name} ne 'HASH'; 

    # otherwise, return true 
    return 1; 
} 

フィルタ名の下にある 'filter_actions'と 'filter_criteria'キーを探します。

sub validate 
{ 
    my ($data, $filter_name) = @_; 

    return if not defined $data->{$filter_name}; 

    return if ref $data->{$filter_name} ne 'HASH'; 

    return if not defined $data->{$filter_name}{filter_actions}; 
    return if not defined $data->{$filter_name}{filter_actions}; 

    # otherwise, return true 
    return 1; 
} 

これだけです! perldoc perlreftootperldoc perlref、およびperldoc perldscのperlデータ構造を使って読んでください。

+0

おそらく、$ data - > {filetername}がハッシュリファレンスであることを確認するべきでしょう。 – DVK

+0

@DVK:よろしくお願いします。 – Ether

+0

より簡潔な方法は 'ref(MY_DAYA_STRUCT)ne ref({}))' – DVK

0

あなたがチェックすることにより、filter_actionsの/ etcにアクセスすることができます$var->{4}->{filter_actions} perlのデータ構造の包括的な概要については、perldscをご覧ください。

0

ここは私のものです。フィルタにデータがあるかどうかを確認するだけです。より構造的な検証が必要な場合は、その部分が後で提供されます。

use List::Util qw<first>; 

sub validate_filter { 
    my ($filters_ref, $filter_name) = @_; 
    my $filter = $filter_name ? $filters_ref->{$filter_name} : $filters_ref; 
    return 1 unless 
     my $missing 
      = first { !!$filter->{ $_ } } 
       qw<name filter_actions filter_criteria> 
     ; 
    if ($missing) { 
     Carp::croak('"Missing '$missing' in filter!"); 
    } 
} 

さて、私の最初に考えたのは、それが構造と名前を受け入れるだろうということでしたが、もちろん、あなたが通過するのに十分を知っている

validate_filter($filters, 4); 

を呼び出すときに十分に知っている:

validate_filter($filters->{4}); 

したがって、パラメータ処理は理解しにくいかもしれませんが、パラメータ渡しという意味では意味があります。

構造の検証後にこのルートを選択することができます。あなたのデータに基づいて、与えられたfilter_criteriaクラスターに3番目のスロットごとに '='演算子がない場合の検証失敗の例を示します。

use Carp  qw<croak>; 
use List::Util qw<first>; 
use Params::Util(); 

sub _test { 
    return 1 if shift->($_); 
    local $Carp::CarpLevel = $Carp::CarpLevel + 2; 
    Carp::croak(shift); 
} 

my $validators 
    = { filter_actions => sub { 
      croak 'filter_actions is not deinfed!' unless defined; 
      _test(\&Params::Util::_HASH, 'filter_actions must be hash!'); 
     } 
     , filter_criters => sub { 
      croak 'filter_criteria is not defined!' unless defined $crit; 
      _test(\&Params::Util::_ARRAY, 'filter_criteria must be non-empty ARRAY!'); 
      foreach (@$crit) { 
       _test(\&Params::Util::_ARRAY, 'criteria must be non-empty ARRAYs'); 
       _test(sub { 
          my $arr = shift; 
          return if @$arr % 3; 
          # return whether any slot in sequence is not '=' 
          return !first { $arr->[$_] ne '=' } 
            # every 3 beginning at 1 
            grep { $_ % 3 == 1 } (1..$#$arr) 
            ; 
         } 
        , 'criteria must be key-value pairs separated by equal sign!' 
        ); 
      } 
     } 
    }; 

そして、これがそうのようなvalidate_filterサブ変更します: - あなたがする必要がありますかどこ質問ヘッダは、あなたが実際に求めているものと一致していないようです

sub validate_filter { 
    my ($filters_ref, $filter_name) = @_; 
    my $filter = $filter_name ? $filters_ref->{$filter_name} : $filters_ref; 
    return 1 unless 
     my $missing 
      = first { 
        return 1 unless $filter->{ $_ }; 
        return unless my $validator = $validators->{ $_ }; 
        local $_ = $filter->{ $_ }; 
        return 1 if $validator->($_); 
       } 
       qw<name filter_actions filter_criteria> 
     ; 
    if ($missing) { 
     Carp::croak("Missing '$missing' in filter!"); 
    } 
} 
関連する問題