Jigar Vaidya
Jigar Vaidya

Reputation: 153

Perl array : Pattern matches then move to the another array

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

Answers (4)

drclaw
drclaw

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

Grinnz
Grinnz

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

cxw
cxw

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

Håkon Hægland
Håkon Hægland

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

Related Questions