Как я могу привязать срез массива к исходному массиву, чтобы все изменения, внесенные в один, были сделаны для обоих?

Мне нужно иметь возможность привязать срез массива к исходному массиву таким образом, чтобы любые изменения, сделанные в исходном массиве (включая удаление элементов), также были добавлены в срез массива. Есть ли способ сделать это?


В следующем примере не работает, как я этого хочу, но он просто показывает, что я пытаюсь сделать.

Пример:

my @array = 1 .. 10;
my @slice = @array[3 .. 8];

splice @array, 5, 2;

print "ARRAY: ";
print join ', ', @array;
print "\n";

print "SLICE: ";
print join ', ', @slice;

Вывод:

ARRAY: 1, 2, 3, 4, 5, 8, 9, 10
SLICE: 4, 5, 6, 7, 8, 9

То, что я ищу, - это способ привязать срез к исходному массиву, чтобы результат выглядел следующим образом:

ARRAY: 1, 2, 3, 4, 5, 8, 9, 10
SLICE: 4, 5, 8, 9

Удаление 6 и 7 из исходного массива также удалит его из среза массива.

Как я могу добиться чего-то подобного?

Ответ 1

Как уже было сказано, это высокий заказ. Краткий ответ: нет. Срез создает копию элементов.

В Perl есть функция Tie, которая может быть просто уловкой.

perltie - how to hide an object class in a simple variable

Так что это в корне меняет то, что переменная находится за кадром. Целый мир возможностей открывается, и ваш сценарий просто может быть там.

perltie на perldoc.perl.org

Ответ 2

Обновлен пост по запросу с использованием объектно-ориентированного метода. Сохранение исходного ответа после <========> строки

Здесь объектно-ориентированный подход, упомянутый в комментариях.
Sample.pm

package Sample;
use strict;
use warnings;
use Exporter qw(import);
use List::MoreUtils qw(first_index);
our @y = qw (3 4 5 6 7 8 9); # Add your method of acquiring @y value here
our @EXPORT = qw (SpliceV2 @y);

##  Your Splice Version 2

sub SpliceV2(@) {
my ($position,$length,@x) = @_;
for (my $i=1;$i<=$length;$i++) {
my $removeditem = $x[$position];
my $remove = first_index { $_ eq $removeditem } @y;
splice @x, $position, 1;
splice @y, $remove, 1;
}

return @x;
}

1;

Основной скрипт:

#!/usr/bin/perl
use Sample;
my @x = qw(1 2 3 4 5 6 7 8 9 10);

@x = SpliceV2(4,2,@x);
print "X: @x\n";
print "Y: @y\n";

Оригинальный пост ниже <==========> Если предположить, что удаляемые элементы уникальны, например, если вы основываете их на первичных ключах базы данных, вы можете использовать first_index из List :: MoreUtils;

Вот образец.

use List::MoreUtils qw(first_index);
my @x = qw (1 2 3 4 5 6 7 8 9 10);
my @y = qw (4 5 6 7 8 9);

## Let say you want to remove 2 items after the 5th index

my $position = 5;
my $length = 2;

##      Get the value of items to remove first

for (my $i=1;$i<=$length;$i++) {
  my $removeditem = $x[$position];
  my $remove = first_index { $_ eq $removeditem } @y;
  splice @x, $position, 1;
  splice @y, $remove, 1;
}
print "Array X\n";
print "$_," foreach(@x);
print "\nArray Y\n";
print "$_," foreach(@y);
print "\n";

Вы должны получить желаемый результат.

Array X
1,2,3,4,5,8,9,10,
Array Y
4,5,8,9,

Ответ 3

use strict;
use warnings;
use Data::Dumper;
my @array = 1..10;
my @slice = \@array[3..8];

splice @array, 5, 2;

print "ARRAY: ";
print join ', ', @array;
print "\n";

print "SLICE: ";
print join ', ', @slice;

Вывод:

ARRAY: 1, 2, 3, 4, 5, 8, 9, 10
SLICE: SCALAR(0x29dcef0), SCALAR(0x29dcf20), SCALAR(0x29dcf08), SCALAR(0x29dcfb0), SCALAR(0x29dcfc, SCALAR(0x29dd058)

Вместо удаления элементов вы можете назначить нулевое значение элементу (оно также назначит нулевое значение в @slice, потому что @slice содержит refference до @array), а затем удаляет 0 из вас @slice и voila, у вас есть обновленный @slice с удаленными элементами