Felix Dombek
Felix Dombek

Reputation: 14382

How can I find an element and remove all following elements?

In other words, I would like to port this simple C++ program to Perl 5:

vector<string> vec { "a", "bb", "ccc", "cd", "ee" };
// find first element starting with "cc"
auto found_it = find_if(begin(vec), end(vec), 
                        [](auto& elem) { return elem.starts_with("cc"); });
// if found, remove all following elements
if (found_it != end(vec)) { vec.erase(found_it + 1, end(vec)); } 

The result should be ("a", "bb", "ccc").

Upvotes: 0

Views: 54

Answers (3)

Polar Bear
Polar Bear

Reputation: 6818

Other variation of perl code to the problem

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my @vec = ("a", "bb", "ccc", "cd", "ee");
my $regex = qr/^cc/;
my $index = 0;

for( @vec ) {
    last if /$regex/;
    $index++;
}

@vec = @vec[0..$index];

say Dumper(\@vec);

Upvotes: 2

Shawn
Shawn

Reputation: 52654

One way is using before_incl from the List::MoreUtils module:

#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use List::MoreUtils qw/before_incl/;

my @vec = ("a", "bb", "ccc", "cd", "ee");
@vec = before_incl { /^cc/ } @vec;
say "@vec"; # a bb ccc

Or a more imperative approach using a loop and splice:

my @vec = ("a", "bb", "ccc", "cd", "ee");
for (my $n = 0; $n < $#vec; $n += 1) {
    if ($vec[$n] =~ /^cc/) {
        splice @vec, $n + 1;
        last;
    }
}

Upvotes: 2

zdim
zdim

Reputation: 66964

One occassion when iterating by index may be useful

foreach my $i (0..$#ary) {
    if ($ary[$i] =~ /^cc/) {
        $#ary = $i;  # shortens the array: last index is now $i
        last;
    }
}

The syntax $#arrayname is for the index of the last element of the array.

Upvotes: 3

Related Questions