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] ];
}
我有两个多维数组: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] ];
}