Perl:难以理解如何访问引用传递的列表列表?

时间:2014-06-29 02:35:24

标签: perl reference pass-by-reference

这是我为遗传/进化算法编写的perl函数,用于比较来自各种文本文档的数据。我试图让复制部分失效:

我的函数调用get_2d_agree_groups,它返回一个"列表列表"通过引用我需要根据需要进一步访问,修改,删除或添加内部列表。 combine_arrayssplit_array获取1d列表并对其进行操作。我无法弄清楚如何正确访问这些内部列表以传递给函数。特别是当我尝试使用combine_arrays附加到内部列表时,它会添加对列表的引用,而不是根据需要添加单个元素。

sub assemble_groups { #(parent1, parent2, new group size)
    my $holder = 0;
    my $parent1 = shift;
    my $parent2 = shift;
    my $num_groups = shift;
    my $blocks = get_2d_agree_groups(\@{${$parent1}{'groups'}},\@{${$parent2}{'groups'}});
    my @disagree_block = pop @{$blocks}; 
    my $agree_size = @{$blocks};
    while($agree_size < $num_groups)
    {
        my $index = getrand(0,($agree_size-1));
        my $size = @{${$blocks}[$index]};
        my $split_index = getrand(0,($size-1));
        my $new_array = split_array(\@{${$blocks}[$index]},$split_index);
        push @{$blocks}, $new_array;
        $agree_size++;
    }
    while($agree_size > $num_groups)
    {
        my $join1 = getrand(0,($agree_size-1));
        my $join2 = getrand(0,($agree_size-1));
        while($join1==$join2)
        {
            $join2 = getrand(0,($agree_size-1));
        }
        my @hold = ${$blocks}[$join2];
        my $test = join('',@hold);
        splice @{$blocks}, $join2, 1;
        combine_arrays(\@{${$blocks}[$join1]},\@hold); #right here
        $agree_size--;
    }
    my $i=0;
    my $disagree_size = @disagree_block;
    while (($i<$agree_size) && $disagree_size)
    {
        getnewgroup(\@{${$blocks}[$i]},\@disagree_block);
        $disagree_size = @disagree_block;
        $i++;
    }
    if($disagree_size)
    {
        combine_arrays(\@{${$blocks}[$i-1]},\@disagree_block); #right here
    }
    return $blocks;
}

相关职能:

sub combine_arrays { #(1d array 1, 1d array)
        my $group1 = shift;
        my $group2 = shift;
        my $group2_size = @{$group2};
        my $next = 0;
        for(my $i=0;$i<$group2_size;$i++)
        {
             $next = @{$group2}[$i];
             push @{$group1}, $next;
        }
}
sub split_array { #(array, index)
      my $old_array = shift;
      my $at = shift;
      my @new_array;
      my $old_size = @{$old_array};
      for(my $i=$at;$i<$old_size;$i++)
      {
           push @new_array, ${$old_array}[$at];
           splice @{$old_array}, $at, 1;
      }
      return \@new_array;
 }

2 个答案:

答案 0 :(得分:2)

my @hold = ${$blocks}[$join2];

的不可读版本
my @hold = $blocks->[$join2];

所以你可能想要取消引用数组,

my @hold = @{ $blocks->[$join2] };

附注

    如果您还没有,请
  • 启用strictwarnings
  • \@{${$blocks}[$join1]}正在引用取消引用的数组,该数组等于${$blocks}[$join1](或$blocks->[$join1]

答案 1 :(得分:1)

您不需要combine_array函数。这是push的用途。

可以从

更改对该功能的两次调用
combine_arrays(\@{${$blocks}[$join1]},\@hold); #right here
...
combine_arrays(\@{${$blocks}[$i-1]},\@disagree_block); #right here

只需致电push

push @{$blocks->[$join1]}, @hold;
...    
push @{$blocks->[$i-1]}, @disagree_block;