arrays - 在 perl 中,如何提取一个已经存在于数组数组中的子数组?
问题描述
@BIG
是一个数组数组。它具有子数组 0、子数组 1 等。我想选择任何子数组,仅通过其索引指定它,并将其确切值(包括其结构)复制或分配给my @extracted_subarray
,而不更改@BIG
。
下面的代码创建并打印了一个@BIG
. 然后最后一行,使用pop
,设法将第二个(索引 1)子数组的值分配给my @extracted_subarray
。这不是我想要的,因为
- 它只获取 的最后一个子数组
@BIG
,而我想通过其索引指定任意现有子数组。 - 它从 中删除子数组
@BIG
,而我想保持@BIG
不受干扰。
当然,必须有一种直接的方法来做到这一点。因为我在R
( r-project.org ) 中编写了很多代码,所以我认为这是一项非常基本的任务。但是“从数组数组中提取子数组”似乎不是正确的搜索词。它为比这个更复杂的问题提供了解决方案。
里面的两个块{...}
在一些阅读这篇文章的人中提出了问题。因此,一个解释。我的实际应用程序不会有这样的硬编码数据元素。我将遍历一个文本文件,其中包含数组各个元素的单独行,并从文本文件构建数组。
特别是,以 开头的@
行将表示一个新的子数组。后面的字符串@
将是@atsign
子子数组中的唯一元素。在此行之后将出现以 开头的任意数量的行=
,它们将成为 @EQsign 子子数组的元素。因此,在实际代码中,每次遇到类似@hrdl:raw_:in:__:
. 并且在每一行一样=\.(((tex)|(txt))|((TEX)|(TXT)))
,另一个元素将被推入@EQsign
。
但前两段与我的问题无关。我的问题是如何提取对应于从 0 到(scalar @BIG) -1)
. 例如,如果我指定索引 1,我希望@extracted_subarray
内容和结构与@tmparray
在迭代 1 中构建的内容和结构相同。在下面的示例中,这意味着@tmparray
存在于第二个块中的 。
我想要@extracted_subarray
并且@BIG
彼此独立存在。两者都不应该仅仅是一个指针或对另一个的引用。因此,如果随后更改@tmparray
或@BIG
更改,我希望其他数组不受影响。
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper qw(Dumper); #https://perlmaven.com/hash-of-arrays
select(STDERR);
my @BIG;
{
my @tmparray;
my @atsign;
my @EQsign;
push @atsign, 'hrdl:raw_:in:__:';
push @EQsign, ( '\.(((tex)|(txt))|((TEX)|(TXT)))' );
push @tmparray, [@atsign];
push @tmparray, [@EQsign];
push @BIG, [@tmparray];
}
{
my @tmparray;
my @atsign;
my @EQsign;
push @atsign, 'hrdl:raw_:EX:__:i';
push @EQsign, ( 'bad words', 'bad\s*word' );
push @EQsign, ( 'forbidden', );
push @tmparray, [@atsign];
push @tmparray, [@EQsign];
push @BIG, [@tmparray];
}
print "BIG=\n"; print Dumper \@BIG;
my @extracted_subarray;
@extracted_subarray = pop @BIG;
print "extracted_subarray=\n"; print Dumper \@extracted_subarray;
解决方案
@BIG
包含对数组的引用。您可以获得以下参考资料之一:
my $sub_array = $BIG[0];
然后,您可以执行for (@$sub_array)
,$sub_array->[0]
等操作。请参阅perlreftut。
请记住,这$BIG[0]
只是对数组的引用,因为您不能将数组放入数组中。要复制参考数组,您可以使用
my @shallow_copy_of_sub_array = @{ $BIG[0] };
您是否会复制$BIG[0]
( @tmparray
) 引用的数组,该数组也是引用的元素,因此@shallow_copy_of_sub_array
并不@BIG
完全独立。例如,更改$shallow_copy_of_sub_array[0][0]
将影响@BIG
. 为了解决这个问题,我们可以使用
my $copy = [
[ $BIG[0][0] ],
[ $BIG[0][1] ],
];
或者我们可以一直复制所有引用的变量。这称为制作深拷贝。
use Storable qw( dclone );
my $deep_copy = dclone($BIG[0]);
或者
use Cpanel::JSON::XS qw( encode_json decode_json );
my $deep_copy = decode_json(encode_json($BIG[0]));
顺便一提,
{
my @tmparray;
my @atsign;
my @EQsign;
push @atsign, 'hrdl:raw_:in:__:';
push @EQsign, ( '\.(((tex)|(txt))|((TEX)|(TXT)))' );
push @tmparray, [@atsign];
push @tmparray, [@EQsign];
push @BIG, [@tmparray];
}
很浪费。您正在免费制作数组的副本。([ @atsign ]
或多或少等同于my @anon = @atsign; \@anon
。) 固定:
{
my @tmparray;
my @atsign;
my @EQsign;
push @atsign, 'hrdl:raw_:in:__:';
push @EQsign, ( '\.(((tex)|(txt))|((TEX)|(TXT)))' );
push @tmparray, \@atsign;
push @tmparray, \@EQsign;
push @BIG, \@tmparray;
}
它仍然是不必要的冗长,妨碍了可读性。固定的:
{
my @atsign = 'hrdl:raw_:in:__:';
my @EQsign = ( '\.(((tex)|(txt))|((TEX)|(TXT)))' );
push @BIG, [ \@atsign, \@EQsign ];
}
你甚至可以使用
push @BIG, [
[ 'hrdl:raw_:in:__:' ],
[ '\.(((tex)|(txt))|((TEX)|(TXT)))' ],
];
这样就清楚多了。
推荐阅读
- sql - 组织外部错误 ORA-29913 ODCIEXTTABLEOPEN
- python - ValueError: Must pass DataFrame only with boolean values - 将 Pandas Columns 转换为 Numeric
- symfony - mp4-file vichuploader Symfony 5 mime 类型验证有时会阻止好视频
- asp.net-core - Asp.Net Core 应用程序 WebSocket(客户端/服务器)
- powerbi - 根据特定日期加上 7 天筛选表
- java - 调用 dispatchTakePictureIntent 时应用程序崩溃
- php - Pest PHP / PHPUnit:使用角色运行测试
- build - Visual Studio 编译器 (VBCSCompiler.exe) 在开始工作前冻结并锁定 CPU 45 秒
- php - 从数据库加载颜色并在背景中列出颜色
- ios - UIPageControl 允许连续交互