Reputation: 153
Perl : I want to move each element of array which matches the pattern.
For example, I have below array @array1 = {cat 2, dog 3#move, tiger 4#move, lion 10}
Now I want to move dog 3, tiger 4 (as pattern #move matches) to another array lets say @array2
foreach $array (@array1) {
if ($array =~ m/(./w*) (./d*)#move/) {
push @array2, $1.$2;
}
But I want to delete those elements from array1. Thanks in advance
Upvotes: 2
Views: 297
Reputation: 2503
A possible solution using List::Util
#!/usr/bin/env perl
#
use warnings;
use strict;
use List::Util qw(pairs pairgrep pairkeys);
my @array1 = ("cat 2", "dog 3#move", "tiger 4#move", "lion 10");
my $i=0;
my @indexList= map { ($i++, $_) } @array1; #build kv pairs
my @removed;
my @filtered=pairgrep { ($b =~ /#move/);} @indexList; #grep kv pairs
push @removed, splice @array1, $_, 1 for (pairkeys @filtered); #splice and push
print "Modified original: @array1\n";
print "Removed elements: @removed\n";
Upvotes: 0
Reputation: 9231
This is what the extract_by function from List::UtilsBy does:
use strict;
use warnings;
use List::UtilsBy 'extract_by';
my @array1 = ("cat 2", "dog 3#move", "tiger 4#move", "lion 10");
my @array2 = map { s/#move//r } extract_by { m/#move/ } @array1;
Upvotes: 1
Reputation: 17051
There is more than one way to do it, so here's another one, inspired by this answer: Use grep
to keep the elements you want. Since Perl only supports deleting elements from the array you're iterating over in certain situations, this does not require you to know which situations those are :) .
use strict; use warnings;
my @array1 = ("cat 2", "dog 3#move", "tiger 4#move", "lion 10");
my @array2;
@array1 = grep { # We are going to search over @array1 and only keep some elements.
if (/(.*)#move/) { # If this is one we want to move...
push @array2, $1; # ... save it in array2...
0; # ... and do not keep it in array1.
} else {
1; # Otherwise, do keep it in array1.
}
} @array1;
# Debug output - not required
print "Array 1\n";
print join "\n", @array1;
print "\nArray 2\n";
print join "\n", @array2;
print "\n";
Output:
Array 1
cat 2
lion 10
Array 2
dog 3
tiger 4
Upvotes: 4
Reputation: 40778
Here is one way:
use feature qw(say);
use strict;
use warnings;
use Data::Printer;
my @array1 = ("cat 2", "dog 3#move", "tiger 4#move", "lion 10");
my @array2;
my @temp;
for my $elem (@array1) {
if ( $elem =~ m/^(.*)#move/) {
push @array2, $1;
}
else {
push @temp, $elem;
}
}
@array1 = @temp;
p \@array1;
p \@array2;
Output:
[
[0] "cat 2",
[1] "lion 10"
]
[
[0] "dog 3",
[1] "tiger 4"
]
Upvotes: 1