Как я могу привязать срез массива к исходному массиву, чтобы все изменения, внесенные в один, были сделаны для обоих?
Мне нужно иметь возможность привязать срез массива к исходному массиву таким образом, чтобы любые изменения, сделанные в исходном массиве (включая удаление элементов), также были добавлены в срез массива. Есть ли способ сделать это?
В следующем примере не работает, как я этого хочу, но он просто показывает, что я пытаюсь сделать.
Пример:
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
с удаленными элементами