Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Array searching, grep, first

by jimbus (Friar)
on Sep 01, 2005 at 17:16 UTC ( #488430=perlquestion: print w/replies, xml ) Need Help??

jimbus has asked for the wisdom of the Perl Monks concerning the following question:


when looping through a list of filenames, I need to see is which element of an array of lines from a CSV file it is and append a couple values to it.

I was thinking of preprocessing the array, parsing the info I need from each line and creating a hash of the substring and the original string, then I could do a direct lookup to modify the original line and walk the keys to regenerate the file. but I was thinking there had to be a more direct way of doing it

I looked at grep and first, but it returns the values and not the element number.

Any thoughts?



Never moon a werewolf!

Replies are listed 'Best First'.
Re: Array searching, grep, first
by ChrisR (Hermit) on Sep 01, 2005 at 17:46 UTC
    I'll agree that it would probably be more efficient to create a hash and work with that, however here is a way to get the array index using grep
    #!c:\perl\bin\perl.exe -w use strict; my @csvlist = qw(file3 file6 file1 file10 file5 file2 file7 file4 file +9 file8); my @listofnames = qw(file1 file2 file3 file4 file5); for my $x(@listofnames) { my ($test) = grep { $csvlist[$_] =~ /$x/} 0..$#csvlist; print "$x found at index: $test\n"; }
    That is, if I understood your question correctly.

    Here is the output from the test script above:

    file1 found at index: 2 file2 found at index: 5 file3 found at index: 0 file4 found at index: 7 file5 found at index: 4
    Update: diotalevi makes a good point below about the inefficient use of grep that I displayed above.

      If you're going to use grep that way, you're doing unnecessary work. Either rewrite that grep as a for loop or use List::Util::first.

      my $index; for ( 0 .. $#csvlist ) { if ( $csvlist[$_] =~ /$x/ ) { $index = $_; last; } } use List::Util 'first'; my $index = first { $csvlist[$_] =~ /$x/ } 0 .. $#csvlist
        You are quite right. grep will search through the entire list on every iteration. first is the way to go but your looping through the indexes is more self explanatory.

      There are usually 90-120 lines in the CSV per day, so I'm not sure it matters.

      Can I get a little explaination on whats going on with grep { $csvlist[$_] =~ /$x/} 0..$#csvlist; it looks like it would be useful.


      Never moon a werewolf!
        What's going on here is that the list that is being greped consists of the numbers 0..$#csvlist. (Or zero through the highest index in the array.) The conditional inside the grep block looks at the array item indexed at each number and returns that number if the condition is true.
Re: Array searching, grep, first
by friedo (Prior) on Sep 01, 2005 at 17:20 UTC
    You're going to have to look through the entire array one way or another. If your data set has more than a few items in it, it will be more efficient to convert the array to a hash and do many lookups on that, instead of doing many searches on your array.
Re: Array searching, grep, first
by eff_i_g (Curate) on Sep 01, 2005 at 17:29 UTC
    i guess this would depend on the size of your CSV; but, would it be silly to do it backwards? that is: open the CSV for in-place editing; for each line run an m// and if you find the file $_ .= 'addition'; #?
Re: Array searching, grep, first
by tye (Sage) on Sep 02, 2005 at 01:20 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://488430]
Approved by friedo
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2022-12-04 21:51 GMT
Find Nodes?
    Voting Booth?

    No recent polls found