splice
是"破坏性的&#34 ;;即它修改了第一个参数"就位#34;。
例如:
DB<63> @a = (0, 1, 2, 3, 4, 5)
DB<64> @b = (20, 30, 40)
DB<65> splice( @a, 2, 3, @b )
DB<66> x \@a
0 ARRAY(0x1daf6e0)
0 0
1 1
2 20
3 30
4 40
5 5
(上方的splice
表达式返回拼接出来的元素,但在这个问题中,我只对slice
的副作用感兴趣。 )
问:是否存在&#34;非破坏性&#34; splice
的对应功能?
E.g。如果上面定义了@a
和@b
,那么所需的non_destructive_splice
函数将会在
@new_a = non_destructive_splice( @a, 2, 3, @b );
...变量@new_a
将保留(0, 1, 20, 30, 40, 5)
,而@a
将保持不变。
答案 0 :(得分:4)
只需复制一份:
my @new_a = @a;
splice( @new_a, 2, 3, @b );
或者如果你想要相同的界面(包括负偏移和可选参数):
sub splice_r(\@;$$@) {
my $num_args = @_;
my $a = shift;
my $offset = shift;
my $len = shift;
my @new_a = @$a;
if ($num_args == 1) { splice(@new_a) }
elsif ($num_args == 2) { splice(@new_a, $offset) }
elsif ($num_args >= 3) { splice(@new_a, $offset, $len, @_) }
return @new_a;
}
my @new_a = splice_r(@a, 2, 3, @b);
或者使用切片来避免不必要的复制:
my @new_a = ( @a[0..1], @b, @a[5..$#a] );
或者如果你想要相同的界面(包括负偏移和可选参数):
sub splice_r(\@;$$@) {
my $num_args = @_;
my $a = shift;
my $i = shift;
my $len = shift;
$i //= 0;
if ($i < 0) {
$i += @$a;
carp("Invalid argument") if $i < 0;
}
elsif ($i > @$a) {
$i = @$a;
}
my $j;
if ($num_args >= 3) {
if ($len >= 0) {
$j = $i + $len;
} else {
$j = @$a + $len;
$j = 0 if $j < 0;
}
} else {
$e = $#$a;
}
return ( @$a[0..$i-1], @_, @$a[$j..$#$a] );
}
my @new_a = splice_r(@a, 2, 3, @b);
答案 1 :(得分:3)
@new_a = @a;
splice @new_a, 2, 3, @b;
答案 2 :(得分:0)
无损版本的接头。我称它为片:
sub slice {
my ($offset, $len) = splice(@_, -2, 2);
my $last = $offset + $len - 1;
return @_[$offset..$last];
}
此:
my @array = qw(a b c d e f g h);
my @cut = slice(@arr, -1, 3); # Even works with wrap-around indexes.
print("@array\n");
print("@cut\n");
结果:
a b c d e f g h
h a b