Как удалить определенный массив в массиве ссылок на массив?
Я заинтересован в удалении конкретного массива из массива ссылок на массивы. С этой целью я перебираю ссылки на массивы и ищу совпадение. Если совпадение найдено, я пытаюсь удалить эту конкретную ссылку на массив, установив ее равной нулю. В написанном мною сценарии происходят две странные вещи: 1) кажется, что код идентифицирует наличие соответствия между интересующим массивом и ссылкой на массив, даже до того, как ссылка на массив, соответствующая ему, будет обработана. 2) Пытаясь удалить одну конкретную ссылку на массив, я в итоге удаляю их все. Вот мой код:
#!/usr/bin/perl
use strict;
use warnings;
my @array_1 = ('CTCTTGCCTCAATCATATAT', 'CTCTTGCCTCATTGATATAT', 'CTCTTGCCTCAATCATATAT', 'CACTTGCCTCAATGAAATTT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGTAATAT', 'CTCTTCCCTCAATGATTTAA', 'CACTTGCCTCAATGATATAT', 'CTCTTGCCTCATTGATATAT', 'CTCTTGCCTCAATGTTATAT', 'CTGATGCCTCATTGATATAT', 'CTGTTGGCTCAATCATATAT');
my @array_2 = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', 'CACTTGCCTCAATGATATAT', 'CTCTTCCCTCAATGATTTAA', 'CTCTTGCCTCAATGTTATAT', 'CTGTTGGCTCAATCATATAT', 'CTGATGCCTCATTGATATAT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGAAATTT');
my @array_3 = ('TATCATTGCCCAATTTAAGT', 'TTTCTTTGCCGAATATAAGT', 'TTTCTATGCGCAATTTAAGT', 'TATCTTAGCCCAATTTTTGT', 'TTTCTTTGCCCAATATATGT', 'TTTCTTTGGCCTATTTTTGT', 'TTTGTTTGGCCATTTTATGT', 'TTTCTTTGGCGAATTTATCT', 'TTTCATTGCCCAATTATTGT', 'TTTCTTTGCCCAAAATAAGT', 'CACTTGCCTCAATGTAATAT');
my @array_4 = ('TTTCTTTGCCCAATATATGT', 'TTTCTTTGCCGAATATAAGT', 'TTTCTATGCGCAATTTAAGT', 'TATCTTAGCCCAATTTTTGT', 'TTTCTTTGGCCTATTTTTGT', 'TTTGTTTGGCCATTTTATGT', 'TTTCTTTGGCGAATTTATCT', 'TTTCATTGCCCAATTATTGT', 'TATCATTGCCCAATTTAAGT', 'TTTCTTTGCCCAAAATAAGT', 'CTCTTGCCTCAATCATATAT');
my $array_1_ref = \@array_1;
my $array_2_ref = \@array_2;
my $array_3_ref = \@array_3;
my $array_4_ref = \@array_4;
my @array_to_delete = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', 'CACTTGCCTCAATGATATAT', 'CTCTTCCCTCAATGATTTAA', 'CTCTTGCCTCAATGTTATAT', 'CTGTTGGCTCAATCATATAT', 'CTGATGCCTCATTGATATAT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGAAATTT');
print "Array to delete: ", join(", ", @array_to_delete), "\n";
my @array_of_array_references = ($array_1_ref, $array_2_ref, $array_3_ref, $array_4_ref);
for (my $i = 0; $i <= $#array_of_array_references; $i++){
print "\n", "A single array in the array of array references: ", join(", ", @{$array_of_array_references[$i]}), "\n";
if (@array_to_delete = @{$array_of_array_references[$i]}){
print "Both arrays match!\n";
@{$array_of_array_references[$i]} = ();
}
}
for (my $i = 0; $i <= $#array_of_array_references; $i++){
print "\n", "A single array in the array of array references after removing one: ", join(", ", @{$array_of_array_references[$i]}), "\n";
}
Выход:
Array to delete: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
A single array in the array of array references: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT
Both arrays match!
A single array in the array of array references: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
Both arrays match!
A single array in the array of array references: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT
Both arrays match!
A single array in the array of array references: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT
Both arrays match!
A single array in the array of array references after removing one:
A single array in the array of array references after removing one:
A single array in the array of array references after removing one:
A single array in the array of array references after removing one:
Ожидаемый результат:
Array to delete: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
A single array in the array of array references: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT
A single array in the array of array references: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
Both arrays match!
A single array in the array of array references: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT
A single array in the array of array references: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT
A single array in the array of array references after removing one: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT
A single array in the array of array references after removing one: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT
A single array in the array of array references after removing one: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT
1 ответ
Код такой как
if (@array_1 == @array_2) # same number of elements?
проверяет, имеют ли массивы одинаковое количество элементов. Это потому что ==
Оператор налагает скалярный контекст на обе стороны, а в скалярном контексте массив вычисляется так, чтобы вернуть количество его элементов.
Чтобы проверить, равны ли массивы, вам нужно сравнить их элементы с несколькими дополнительными проверками и уточнениями. Что касается многих вещей в Perl, есть также модули, которые делают это для нас.
С Array:: Compare, например, в его простейшем использовании:
use Array::Compare;
my $comp = Array::Compare->new;
...
if ($comp->compare(\@ary1, \@ary2)) # they are equal
С помощью модуля можно настроить и другие функции, а также ряд других модулей для всех видов работы с массивами и списками.
Код в вопросе также использует =
(назначение!) вместо сравнения ==
,
С несколькими упрощениями
use warnings;
use strict;
use Data::Dump qw(dd); # to show complex data structures
use Array::Compare;
my $cobj = Array::Compare->new;
my @data = (
['CTCTTGCCTCAATCATATAT', 'CTCTTGCCTCATTGATATAT', ... ],
['CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', ... ],
...
);
my @ary_to_del = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', ...);
foreach my $ra (@data) {
@$ra = () if $cobj->compare(\@ary_to_del, $ra);
}
dd \@data;
Это "очищает" анонимные массивы в @data
которые равны @ary_to_del
, как и код в вопросе, но их ссылки на массив остаются в @data
хотя в них ничего нет.
Если вы хотите удалить такие элементы вообще, перезапишите массив
@data = grep { not $cobj->compare(\@ary_to_del, $_) } @data;
вместо foreach
петля выше. Это использует grep для фильтрации входного списка, в результате чего только те элементы, для которых блок кода оценивает true, возвращаются в выходной список, назначенный @data
,