Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Grep question

by hok_si_la (Curate)
on Feb 03, 2005 at 17:25 UTC ( #427720=perlquestion: print w/replies, xml ) Need Help??
hok_si_la has asked for the wisdom of the Perl Monks concerning the following question:

I have the following code:
my @statusoption = ('Waiting Approval' , 'Denied' , 'Approved' , 'Orde +rred' , 'Building' , 'Built' , 'Shipped'); my $i = 0; while ($status ne @statusoption[$i]){ ++$i; } @statusoption = splice(@statusoption, $i);

Is there a way to use Grep or a similar function to find the index of $status and pop the rest all in one line?


Replies are listed 'Best First'.
Re: Grep question
by Tanktalus (Canon) on Feb 03, 2005 at 17:28 UTC
    { my $i; @statusoption = grep { $i or ($_ eq $status && ++$i) } @statusoption +; }
Re: Grep question
by Roy Johnson (Monsignor) on Feb 03, 2005 at 17:42 UTC
    Yes, though I'm not sure I'd recommend it over the other solutions posted:
    @statusoption = splice(@statusoption, (grep $statusoption[$_] eq $status, 0..$#statusoption)[0]);
    Update: No need for splice when you just want a slice:
    @statusoption = @statusoption[ (grep {$status eq $statusoption[$_]} 0..$#statusoption)[0] ..$#statusoption];
    Update: But splice is better than reassignment:
    splice(@statusoption, 0, (grep $status eq $statusoption[$_], 0..$#stat +usoption)[0]);
    Here's one that will short-circuit :-D:
    splice(@statusoption, 0, &{sub { grep {$status eq $statusoption[$_] and return $_} 0..$#statusop +tion }} );

    Caution: Contents may have been coded under pressure.
      Thanks all of you. I have made the suggested changes. I will need to look at them more in depth.

      I have a similar question for those of you with patience. I am trying to remove an item from an array using the delete function. Here is the code:
      @statusoption = ('Waiting Approval' , 'Denied' , 'Approved' , 'Ordered +' , 'Building' , 'Built' , 'Shipped'); delete $statusoption[3];
      This simply yields ('Waiting Approval' , 'Denied' , 'Approved' , '' , 'Building' , 'Built' , 'Shipped')
      I would like to remove 'Ordered' from the array and shift all the other elements down an index truncating the array by 1.

      I appreciate you help,
        That's what splice is for:
        splice(@statusoption, 3, 1);

        Caution: Contents may have been coded under pressure.
Re: Grep question
by saintmike (Vicar) on Feb 03, 2005 at 17:32 UTC
    First off, instead of @statusoption[$i] (which returns an array slice) please use $statusoption[$i] which returns an array element. Secondly, you could use grep to set a status flag once you've found what you're looking for:
    my $found; @statusoption = grep { $found++ if $_ eq $status; $found } @statusoption;
Re: Grep question
by moot (Chaplain) on Feb 03, 2005 at 18:03 UTC
    Not sure why you need to "pop the rest". If all you're trying to do is find the index of the status value itself, what's wrong with:
    my %statusoption = ( "Waiting Approval" => 0, "Denied" => 1, "Approved" => 2, "Ordered" => 3, "Building" => 4, "Built" => 5, "Shipped" => 6, ); my $statusoption = $statusoption{$status};
    This assumes an item can't have more than one status, but since you're using a scalar to hold it that's not a bad assumption.
      I will post the more code to give you guys a better idea of what I am trying to accomplish. I have no problem getting this to work, but I have been cleaning it up a bit. Originally it was about 40 lines, and now I have it down to this. In the process I am learning about perl Data structures.

      ###--- Define options for select Status ---### @statusoption = ('Waiting Approval' , 'Denied' , 'Approved' , 'Ordered +' , 'Building' , 'Built' , 'Shipped'); if ($purchase eq "Already Have") { delete @statusoption[3]; } if ($purchase eq "Virtual Machine") { delete @statusoption[3]; delete $statusoption[6]; } @statusoption = grep {$found++ if $_ eq $status; $found } @statusoptio +n; ###----------------------------------------###
        Actually the code is as follows
        ###--- Define options for select Status ---### @statusoption = ('Waiting Approval' , 'Denied' , 'Approved' , 'Ordered +' , 'Building' , 'Built' , 'Shipped'); if ($purchase eq "Already Have") { delete $statusoption[3]; } if ($purchase eq "Virtual Machine") { delete $statusoption[3]; delete $statusoption[6]; } @statusoption = grep {$found++ if $_ eq $status; $found } @statusoptio +n; ###----------------------------------------###
Re: Grep question
by sh1tn (Priest) on Feb 03, 2005 at 21:06 UTC
    my @statusoption = ('Waiting Approval' , 'Denied' , 'Approved' , 'Orde +rred' , 'Building' , 'Built' , 'Shipped'); my $status = 'Approved'; my ($position, $flag); my @popped = grep{ $flag and $_ or $_ eq $status and $flag++ or $position++, 0 }@statusoption; print "position:$position new: @popped$/" __END__ position:3 new: Orderred Building Built Shipped

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://427720]
Approved by Tanktalus
and the radiator hisses contentedly...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2017-04-26 11:36 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (473 votes). Check out past polls.