2

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

3
  • 1
    Your pattern contains only one capture group, so it's unclear what $2 is expected to be. Commented May 6, 2019 at 16:53
  • 1
    Can you describe more clearly what @array1 contains? It is not the correct way to instantiate a Perl array, and the regex you provide would not match since there's no comma before #move. (and a word character is \w, not /w) Commented May 6, 2019 at 16:55
  • updated the array and regex, thanks for point it out Commented May 6, 2019 at 20:21

4 Answers 4

4

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
Sign up to request clarification or add additional context in comments.

Comments

1

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"
]

Comments

1

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;

Comments

0

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";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.