How to delete a specific array in an array of array references?
Code such as
if (@array_1 == @array_2) # same number of elements?
tests whether the arrays have the same number of elements. This is because the ==
operator imposes the scalar context on both sides, and in scalar context an array is evaluated to return the number of its elements.
To test whether arrays are equal you need to compare their elements, with a few additional checks and refinements. As for many things in Perl, there are also modules that do that for us.
With Array::Compare for example, in its simplest usage:
use Array::Compare;
my $comp = Array::Compare->new;
...
if ($comp->compare(\@ary1, \@ary2)) # they are equal
There is more that can be set up with the module, and there is a number of other modules for all kind of work with arrays and lists.
The code in the question also uses =
(assignment!) instead of comparison ==
.
With a few simplifications
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;
This "empties" the anonymous arrays in @data
that are equal to @ary_to_del
, as code in the question does, but their array references remain in @data
even as there is nothing in them.
If you were rather to remove such elements altogether then overwrite the array
@data = grep { not $cobj->compare(\@ary_to_del, $_) } @data;
instead of the foreach
loop above. This uses grep to filter the input list, whereby only elements for which the code block evaluates true are returned in the output list, assigned to @data
.
Remove all elements contained in another array
Use the Array.filter()
method:
myArray = myArray.filter( function( el ) {
return toRemove.indexOf( el ) < 0;
} );
Small improvement, as browser support for Array.includes()
has increased:
myArray = myArray.filter( function( el ) {
return !toRemove.includes( el );
} );
Next adaptation using arrow functions:
myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
remove object from array with just the object's reference
Simply use Array.prototype.indexOf
:
let index = MyArray.indexOf(TheObject);
if(index !== -1) {
MyArray.splice(index, 1);
}
Keep in mind that if targeting IE < 9 you will need to introduce a polyfill for indexOf
; you can find one in the MDN page.
Related Topics
My Button Is Centered for iPhone 6 and 6 Plus, But Not for iPhone 5
Store Data in Custom Class Array in Core Data
Code Only Retrieving One Value from Data in Firebase
Could Not Cast Value of Type Uiview to [Customview] Using Xib
How to Unpack Multiple Levels of Nested JSON in Firebase Database
Avaudioplayer.Play() Works But Avaudioplayernode.Play() Fails
iOS 13 Swiftui: App Crashes Upon Launch on Real Device
Generic Class with Class-Bound Constraint Cannot Be Parametrized by Class-Bound Protocol
Collection View Layout Bug When Selectitem (Swift 5)
Swift: Filter a Dictionary with Array as Value
Undefined Symbol Objc_Class_$ When Creating iOS Framework
Filtering Dictionary in Swift 4 Fails in Xcode, But Succeeds in Playground
How to Read Ansi Escape Code Response Value in Swift
Exc Bad Access After Coding Signing
How to Give Dynamic Height to Uitableview
Swiftui - Mapkit - Binding Mapkit and Show View on Annotation Callout Buttons