寻找`splice ARRAY,OFFSET,LENGTH,LIST`的非破坏性对应物

时间:2017-07-06 16:40:56

标签: perl

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保持不变

3 个答案:

答案 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