Perl:如何向多维数组中的每一行添加附加列

Perl: How to add additional column to each row in multi-dimensional array

我有两个多维数组:array1(@wipr) 和 array2(@widesc)

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
  
# Initializing and defining the array
my @wipr = ( ['1111', '2221'],
              ['1112', '2222'],
              ['1113', '2223'],
              ['1115', '2225'],
              ['1113', '2224'] );
my @widesc = ( ['1111', 'Bug1'],
              ['1112', 'Feature1'],
              ['1113', 'Feature2'],
              ['1114', 'Feature2'] );
# Printing items from the array
#print Dumper(\@wipr);
#print Dumper(\@widesc);

# Using For loop
for(my $m = 0; $m <= $#wipr; $m++)
{   
   for(my $n = 0; $n <= $#widesc ; $n++)
   {  
      #print $wipr[$m][0], "\n";
      #print $widesc[$n][0];
      if ( "$wipr[$m][0]" == "$widesc[$n][0]" )
      {
          print "Matches: $wipr[$m][0] == $widesc[$n][0]";
          my $desc="$widesc[$n][1]";
          print "desc value is : $desc";
          #push(@{$wipr[$m][1][$m]},"$desc");
          #print "$wipr[$m][1][$m]";
          $wipr[$m][1][$m] = "'$desc'";
          #push (@wipr,$wipr[$m][1][$m]);
      }
      #else
      #{
        #  print "Doesn't Matches: $wipr[$m][0] == $widesc[$n][0]";
      #}
   }  
   print "\n";  
} 
print Dumper(\@wipr);

如果 array1(@wipr) 中第一列的值与 array2(@widesc) 中第一列的值匹配,我们需要将 array2 的第二个元素添加到 array1 中。 如果值不匹配,它应该只是放一个字符串“未找到”

所需输出应为:

 my @result= ( ['1111', '2221', 'Bug1'],
                  ['1112', '2222', 'Feature1'],
                  ['1113', '2223', 'Feature2'],
                  ['1115', '2225', 'Not Found'],
                  ['1113', '2224', 'Feature2'] );

我无法在 array1 中添加第三列。你能帮忙吗

错误: 无法使用字符串 ("2221") 作为数组引用,而在 arrays1.pl line33 使用“严格引用”。

朴素的方式:

my @result;
for my $wipr (@wiprs)
   my $wi1 = $wipr->[0];

   for my $widesc (@widescs)
      my $wi2 = $widesc->[0];
      if ($wi1 == $wi2) {
         push @result, [ $wi1, $wipr->@[1..$#$wipr],  $widesc->@[1..$#$widesc] ];
         last;
      }
   }
}

这很慢。如果有N个WI,则内层循环执行N*N/2次。这意味着花费的时间与 N2.

的平方成正比

当某物占用的资源(例如时间)与 N2 的平方成正比时,我们说它是 O(N2) .


上面之所以这么慢是因为匹配记录的过程。如果对数组进行排序会怎样?

@wiprs   = sort { $a->[0] <-> $b->[0] } @wiprs;
@widescs = sort { $a->[0] <-> $b->[0] } @widescs;

my $pr_i = 0;
my $desc_i = 0;

my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
   my $wipr   = $wiprs[$pr_i];
   my $widesc = $widescs[$desc_i];

   my $wi1 = $wipr->[0];
   my $wi2 = $wipdesc->[0];

   my $cmp = $wi1 <=> $wi2;
   if ($cmp < 0) {
      ++$pr_i;
   }
   elsif ($cmp > 0) {
      ++$desc_i;
   }
   else {
      push @result, [ $wi1, $wipr->@[1..$#$wipr],  $widesc->@[1..$#$widesc] ];
      ++$pr_i;
      ++$desc_i;
   }
}

这是 O(N log N)。好很多

如果我们假设有两个数组具有完全相同的 WI,则以上内容可简化为:

die "Bad data\n" if @wiprs != @widescs;

@wiprs   = sort { $a->[0] <-> $b->[0] } @wiprs;
@widescs = sort { $a->[0] <-> $b->[0] } @widescs;

my $pr_i = 0;
my $desc_i = 0;

my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
   my $wipr   = $wiprs[$pr_i];
   my $widesc = $widescs[$desc_i];

   my $wi1 = $wipr->[0];
   my $wi2 = $wipdesc->[0];

   die "Bad data\n" if $wi1 != $wi2;

   push @result, [ $wi1, $wipr->@[1..$#$wipr],  $widesc->@[1..$#$widesc] ];
   ++$pr_i;
   ++$desc_i;
}

当然,如果数组已经排序,则简化为如下O(N)的解决方案:

die "Bad data\n" if @wiprs != @widescs;

my $pr_i = 0;
my $desc_i = 0;

my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
   my $wipr   = $wiprs[$pr_i];
   my $widesc = $widescs[$desc_i];

   my $wi1 = $wipr->[0];
   my $wi2 = $wipdesc->[0];

   die "Bad data\n" if $wi1 != $wi2;

   push @result, [ $wi1, $wipr->@[1..$#$wipr],  $widesc->@[1..$#$widesc] ];
   ++$pr_i;
   ++$desc_i;
}

最后,我们先建立一个索引,得到一个没有上述假设的O(N)解。

my %widescs_lookup;
for my $widesc (@widescs)
   my $wi = $widesc->[0];
   $widescs_lookup{$wi} = $widesc;
}

my @results;
for my $wipr (@wiprs)
   my $wi = $wipr->[0];

   my $wi_desc = $widescs_lookup{$wi}
      or next;

   push @result, [ $wi1, $wipr->@[1..$#$wipr],  $widesc->@[1..$#$widesc] ];
}