简体   繁体   English

Perl循环通过嵌套的有祝福的hashref元素

[英]Perl loop thru nested blessed hashref elements

I have a perl data structure similar to the following: 我有一个类似于以下内容的perl数据结构:

$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' );

I am looking for a way to loop thru all the groups in 'groups_list' and check if we have 'webuser' groupid in it. 我正在寻找一种方法来循环遍历“ groups_list”中的所有组,并检查是否有“ webuser” groupid。 Any help is appreciated. 任何帮助表示赞赏。

Also, kindly let me know if this can be done without using a loop.. something like searching for the string 'groupid' => 'webuser' .. 另外,请告诉我是否可以在不使用循环的情况下完成此操作。类似搜索字符串'groupid'=>'webuser' ..

bless ing reference only add arbitrary type description to it and doesn't change working with it in any other way, unless you use overload , so exactly same loop as with unblessed references will work: bless引用只会在其中添加任意类型描述,并且不会以任何其他方式更改它,除非您使用了overload ,因此与未bless引用完全相同的循环将起作用:

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

You can also replace loop with grep if you only need inner hashes with data without their indices in array: 如果只需要带有数据的内部哈希,而数组中没有索引,则也可以用grep替换loop:

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

This will search entire list though. 但这将搜索整个列表。 Use first from List::Util to only find first match. List::Util使用first只能找到第一个匹配项。

This will loop through and find it: 这将遍历并找到它:

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

You can't really do this without looping, because your task inherently involves looking at each element. 如果没有循环,就无法真正做到这一点,因为您的任务本质上涉及查看每个元素。

Since the groups have been blessed into a package, you should probably not be checking for the existence of hash keys directly, instead add a method to the group_entry class like this (something similar may already exist): 由于组已被打包,因此您可能不应该直接检查哈希键的存在,而应像这样向group_entry类添加一个方法(可能已经存在类似的方法):

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

and since your data is also blessed into the user_info package, create a method on user_info to filter the groups by groupid (your user_info class may already have something like this): 并且由于您的数据也被添加到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
  }
}

and in your code, do something like: 然后在您的代码中执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM