2012-10-18 22 views
1

我有類似如下的Perl數據結構:Perl的環通嵌套祝福hashref元素

$VAR1 = bless({ 
       'admin' => '0', 
       'groups_list' => [ 
              bless({ 
                'name' => undef, 
                'groupid' => 'canedit', 
                'description' => 'Can Edit Articles' 
                }, 'group_entry'), 
              bless({ 
                'name' => undef, 
                'groupid' => 'webuser', 
                'description' => 'Can Access Content' 
                }, 'group_entry'), 
             ], 
       'trusted' => '1', 
       }, 'user_info'); 

我在「groups_list」尋找一種方式來環通所有的團體和檢查,如果我們有' webuser'groupid。任何幫助表示讚賞。

另外,請讓我知道,如果這可以在不使用循環..像搜索的字符串做「組識別符號」 =>「WEBUSER」 ..

+1

某些東西將不得不循環哈希以字符串形式轉儲,因此無論是在您的代碼還是在幕後,循環都將發生。除了破解封裝外,其餘的都是 – vol7ron

回答

5

bless荷蘭國際集團僅供參考添加任意類型說明它並不會改變以任何其他方式使用它,除非你使用overload,所以完全一樣環與unblessed引用將工作:

foreach my $group (@{$VAR1->{groups_list}}) { 
    if ($group->{groupid} eq 'webuser') { 
     # do stuff and break out 
    } 
} 

你也可以用grep代替循環,如果你只在陣列需要的數據散列內沒有他們的指標:

my @webusers = grep { $_->{groupid} eq 'webuser' } @{$VAR1->{groups_list}}; 

這雖然搜索整個列表。從List::Util使用first只能找到第一個匹配項。

+0

。 – MkV

+0

@MkV,沒有提到它是否會在班級內外使用。 –

3

這將遍歷並發現它:

foreach (@{$VAR1->{'groups_list'}}) 
{ 
    if ($_->{'groupid'} eq 'webuser') 
    { 
     print "found webuser."; 
    } 
} 

如果沒有循環,你不能真正做到這一點,因爲你的任務固有地涉及到每個元素。

0

由於集團一直在祝福成一個包,你可能不應該直接檢查哈希鍵的存在,而不是添加一個方法到group_entry類這樣的(類似的東西可能已經存在):

{ 
    package group_entry; 
    sub get_groupid { 
    my $self = shift; 
    $self->{groupid} 
    } 
} 

而且由於你的數據也祝福到USER_INFO包,創建USER_INFO的方法通過GROUPID過濾組(您USER_INFO類可能已經有這樣的事):

{ 
    package user_info; 
    sub get_groups_list { 
    my $self = shift; 
    return @{ $self->{groups_list} } 
    } 
    sub filter_groups_by_groupid { 
    my $self = shift; 
    my ($filter_groupid) = @_; 
    return grep { $_->get_groupid eq $filter_groupid } $self->get_groups_list 
    } 
} 

,並在你的代碼,做類似於:

my @webusers = $data->filter_groups_by_groupid('webuser');