如何在 Perl 中将一个数组分成两个不同的数组
How to divide an array in to two different arrays in Perl
我有一个哈希数组,我需要将它分成两个不同的数组。哈希数组如下所示:
old_array = [
{
'a'=>1,
'b'=>2,
'c'=>3,
'd'=>4
},
{
'e'=>5,
'f'=>6,
'g'=>7,
'h'=>8
},
{
'i'=>9,
'j'=>10,
'k'=>11,
'l'=>12
},
{
'm'=>13,
'n'=>14,
'o'=>15,
'p'=>16
}
];
我需要按照以下方式将它分成两个不同的数组:
new_array_1 = [{
'a'=>1,
'b'=>2,
'c'=>3,
'd'=>4
},
{
'e'=>5,
'f'=>6,
'g'=>7,
'h'=>8
}
];
new_array_2 = [{
'i'=>9,
'j'=>10,
'k'=>11,
'l'=>12
},
{
'm'=>13,
'n'=>14,
'o'=>15,
'p'=>16
}
];
我现在已经尝试了其中一个答案中提到的以下代码:
my ($new_array_1, $new_array_2) =
map { [ $_ ] }
@$old_array;
这是拆分数组但删除了中间的哈希值,我得到的输出为:
$VAR1 = [
{
'c' => 3,
'a' => 1,
'b' => 2,
'd' => 4
}
];
$VAR1 = [
{
'g' => 7,
'f' => 6,
'e' => 5,
'h' => 8
}
];
我应该怎么做才能得到想要的输出?哈希可能会增加到 10 或 20 或 15 等
问题发生了重大变化,现在 arrayref 不再有两个元素,而是更多,它需要拆分,以便它的两半进入两个数组。元素不需要做成 arrayrefs.
现在必须去索引。 (好吧,或者在 moving/copying 逐个元素的同时在新数组之间交替。)一种方式
my $midind = ($#$old_arrayref-1)/2; # or: (@$oldarrayref/2)-1
my $new_arrayref_1 = [ @$old_arrayref[0..$midind] ];
my $new_arrayref_2 = [ @$old_arrayref[$midind+1 .. $#$old_array] ];
这会保留原来的数组。 (语法 $#$arrayref
用于数组引用 $arrayref
中的最后一个索引。)如果旧数组无关紧要,可以改为
my $new_arrayref_1 = [ splice @$old_arrayref, 0, $midind+1 ];
my $new_arrayref_2 = [ @$old_arrayref ];
注意 如果原始数组的元素本身包含复杂的数据结构(因此,引用),那么它们需要被“深度复制”,例如使用 Storable::dclone
.
我仍然建议阅读原始 post(下方)中链接的资源,以了解如何使用这种语言使用数组。
原答案。更改之前的问题是初始数组 (ref) 严格包含两个元素,一旦将它们拆分为两个数组,它们(表面上)需要包装到 arrayrefs 中。这对于基本资源列表应该仍然有用(如果 reader 需要)。
Perl 支持对数组的一系列操作。至于基础,我们可以从前面或后面删除和 return 一个元素,用 shift 或 pop
,可以用 unshift
或 push
添加。
然后还有更多,包括splice
你试过的,还有更复杂操作的库。但是基础知识很容易解决您的问题。一种方式
my $old_arrayref = [ { a=>1, b=>2 }, { c=>3, d=>4 } ];
my @new_array_1 = shift @$old_array;
my @new_array_2 = shift @$old_array;
(一个 array 可以简单地分配一个元素列表,包括一个元素。但是如果数组中有任何东西,那么在这样的分配之后它就会全部消失所以不要忘记这一点。 )
在这里,我将源 (old_array
) 作为数组引用,紧接着问题。现在 $old_array
是空的,如果它只有那两个元素,它们现在在 @new_array_N
中。 †
另一种更基本的方法是 index into the array 访问单个元素并将它们复制到新数组。这样 $old_array
就会保持原样。
也许更合理的安排是将这两个新数组的引用作为数组的元素,这可能是您的代码试图做的。为此,您只需要 †
my @new_array = map { [ $_ ] } @$old_array;
map applies the code in the block to each element of its input (@$old_array
), returning a list, assigned to @new_array
. That []
in the body constructs an anonymous array (reference), which is a scalar and as such can be placed on an array. The only element placed in this array-reference is the currently processed element of @$old_array
, available in the (ubiquitous) $_
variable.
参见上面的 perlintro
和 perldata
链接,以及 shift
中的链接。对于库中提供的列表和数组的许多其他操作,请参阅 List::Util and List::MoreUtils 初学者。
有关参考资料,请参阅 perlreftut and for arrays with references see perllol (lists-of-lists) and perldsc(数据结构指南)。
一个完整的程序†
use warnings;
use strict;
use feature 'say';
use Data::Dumper;
my @old_array = ( { 'a'=>1, 'b'=>2 }, { 'c'=>3, 'd'=>4 } );
my @new_array = map { [ $_ ] } @old_array;
say Dumper \@new_array;
这会打印出来(只是压缩,以便于阅读 post)
$VAR1 = [
[ { 'a' => 1, 'b' => 2 } ],
[ { 'c' => 3, 'd' => 4 } ]
];
† 如果新数组也需要数组引用
my $new_arrayref_1 = [ shift @$old_array ];
my $new_arrayref_2 = [ shift @$old_array ];
在第二个例子和简短的“完整程序”中
my $new_arrayref = [ map { [ $_ ] } @$old_array ];
你基本上答对了。你原来有
my @new_array;
push @new_array, [ splice @$missingSections, 0, 2 ] while @$old_array;
应该是
my @new_array;
push @new_array, [ splice @$old_array, 0, 2 ] while @$old_array;
也可以这样写:
use List::MoreUtils qw( natatime );
my @new_array;
my $iter = natatime 2, @$old_array;
while ( my @vals = $iter->() ) {
push @new_array, \@vals;
}
my @new_array =
map [ $old_array->@[ $_*2+0, $_*2+1 ] ],
0..@$old_array/2;
use List::Util qw( pairs );
my @new_array = pairs @$old_array;
use List::MoreUtils qw( part );
my @new_array = part { $_/2 } 0..$#$old_array;
我有一个哈希数组,我需要将它分成两个不同的数组。哈希数组如下所示:
old_array = [
{
'a'=>1,
'b'=>2,
'c'=>3,
'd'=>4
},
{
'e'=>5,
'f'=>6,
'g'=>7,
'h'=>8
},
{
'i'=>9,
'j'=>10,
'k'=>11,
'l'=>12
},
{
'm'=>13,
'n'=>14,
'o'=>15,
'p'=>16
}
];
我需要按照以下方式将它分成两个不同的数组:
new_array_1 = [{
'a'=>1,
'b'=>2,
'c'=>3,
'd'=>4
},
{
'e'=>5,
'f'=>6,
'g'=>7,
'h'=>8
}
];
new_array_2 = [{
'i'=>9,
'j'=>10,
'k'=>11,
'l'=>12
},
{
'm'=>13,
'n'=>14,
'o'=>15,
'p'=>16
}
];
我现在已经尝试了其中一个答案中提到的以下代码:
my ($new_array_1, $new_array_2) =
map { [ $_ ] }
@$old_array;
这是拆分数组但删除了中间的哈希值,我得到的输出为:
$VAR1 = [
{
'c' => 3,
'a' => 1,
'b' => 2,
'd' => 4
}
];
$VAR1 = [
{
'g' => 7,
'f' => 6,
'e' => 5,
'h' => 8
}
];
我应该怎么做才能得到想要的输出?哈希可能会增加到 10 或 20 或 15 等
问题发生了重大变化,现在 arrayref 不再有两个元素,而是更多,它需要拆分,以便它的两半进入两个数组。元素不需要做成 arrayrefs.
现在必须去索引。 (好吧,或者在 moving/copying 逐个元素的同时在新数组之间交替。)一种方式
my $midind = ($#$old_arrayref-1)/2; # or: (@$oldarrayref/2)-1
my $new_arrayref_1 = [ @$old_arrayref[0..$midind] ];
my $new_arrayref_2 = [ @$old_arrayref[$midind+1 .. $#$old_array] ];
这会保留原来的数组。 (语法 $#$arrayref
用于数组引用 $arrayref
中的最后一个索引。)如果旧数组无关紧要,可以改为
my $new_arrayref_1 = [ splice @$old_arrayref, 0, $midind+1 ];
my $new_arrayref_2 = [ @$old_arrayref ];
注意 如果原始数组的元素本身包含复杂的数据结构(因此,引用),那么它们需要被“深度复制”,例如使用 Storable::dclone
.
我仍然建议阅读原始 post(下方)中链接的资源,以了解如何使用这种语言使用数组。
原答案。更改之前的问题是初始数组 (ref) 严格包含两个元素,一旦将它们拆分为两个数组,它们(表面上)需要包装到 arrayrefs 中。这对于基本资源列表应该仍然有用(如果 reader 需要)。
Perl 支持对数组的一系列操作。至于基础,我们可以从前面或后面删除和 return 一个元素,用 shift 或 pop
,可以用 unshift
或 push
添加。
然后还有更多,包括splice
你试过的,还有更复杂操作的库。但是基础知识很容易解决您的问题。一种方式
my $old_arrayref = [ { a=>1, b=>2 }, { c=>3, d=>4 } ];
my @new_array_1 = shift @$old_array;
my @new_array_2 = shift @$old_array;
(一个 array 可以简单地分配一个元素列表,包括一个元素。但是如果数组中有任何东西,那么在这样的分配之后它就会全部消失所以不要忘记这一点。 )
在这里,我将源 (old_array
) 作为数组引用,紧接着问题。现在 $old_array
是空的,如果它只有那两个元素,它们现在在 @new_array_N
中。 †
另一种更基本的方法是 index into the array 访问单个元素并将它们复制到新数组。这样 $old_array
就会保持原样。
也许更合理的安排是将这两个新数组的引用作为数组的元素,这可能是您的代码试图做的。为此,您只需要 †
my @new_array = map { [ $_ ] } @$old_array;
map applies the code in the block to each element of its input (@$old_array
), returning a list, assigned to @new_array
. That []
in the body constructs an anonymous array (reference), which is a scalar and as such can be placed on an array. The only element placed in this array-reference is the currently processed element of @$old_array
, available in the (ubiquitous) $_
variable.
参见上面的 perlintro
和 perldata
链接,以及 shift
中的链接。对于库中提供的列表和数组的许多其他操作,请参阅 List::Util and List::MoreUtils 初学者。
有关参考资料,请参阅 perlreftut and for arrays with references see perllol (lists-of-lists) and perldsc(数据结构指南)。
一个完整的程序†
use warnings;
use strict;
use feature 'say';
use Data::Dumper;
my @old_array = ( { 'a'=>1, 'b'=>2 }, { 'c'=>3, 'd'=>4 } );
my @new_array = map { [ $_ ] } @old_array;
say Dumper \@new_array;
这会打印出来(只是压缩,以便于阅读 post)
$VAR1 = [ [ { 'a' => 1, 'b' => 2 } ], [ { 'c' => 3, 'd' => 4 } ] ];
† 如果新数组也需要数组引用
my $new_arrayref_1 = [ shift @$old_array ];
my $new_arrayref_2 = [ shift @$old_array ];
在第二个例子和简短的“完整程序”中
my $new_arrayref = [ map { [ $_ ] } @$old_array ];
你基本上答对了。你原来有
my @new_array;
push @new_array, [ splice @$missingSections, 0, 2 ] while @$old_array;
应该是
my @new_array;
push @new_array, [ splice @$old_array, 0, 2 ] while @$old_array;
也可以这样写:
use List::MoreUtils qw( natatime );
my @new_array;
my $iter = natatime 2, @$old_array;
while ( my @vals = $iter->() ) {
push @new_array, \@vals;
}
my @new_array =
map [ $old_array->@[ $_*2+0, $_*2+1 ] ],
0..@$old_array/2;
use List::Util qw( pairs );
my @new_array = pairs @$old_array;
use List::MoreUtils qw( part );
my @new_array = part { $_/2 } 0..$#$old_array;