Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

using split on every element in an array

by Anonymous Monk
on Jan 17, 2003 at 15:10 UTC ( [id://227691]=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks, I am having problems I have a file containing lots of tab-delimited information seperated by newline characters. I have split the array on every new-line character into elements  my @data = split /\n/, $data;. I next want to split each element up on every tab..... how can i do this as each element is effectively a scalar and can't be split?? Also I want to keep the elements of @data intact for working with later. I tried
foreach my $item (@data) { split /\t/; }
but it didn't work. Another problem is the program needs to be able to cope with varying amounts of data e.g. the number of elements in @data will change each time. Hope I have explained this clearly enough. Thanks x

Replies are listed 'Best First'.
Re: using split on every element in an array
by Fletch (Bishop) on Jan 17, 2003 at 15:15 UTC

    You're calling split() in a void context, so whatever returned values it may be generating are just being discarded. You'd want to do something like push @split_data, split( /\t/ ) to save them off.

    Or even better, look at Text::CSV_XS and see if that'll handle your data parsing needs.

      Is it possible to automatically convert every element of an array into a newly named scalar variable (each of which has a different name)??

        Every element of an array is a named scalar variable.

        Eg. $array[3] = 'something';  $var = $array[4]; etc.

        You can therefore use them directly with split.

        Eg.

        for my $element (@array) { my @bits = split "\t", $element; #do something with the bits. }

        The contents of @array will remain unmodified for further use later unless you assign something to $element.

        It might be clearer to you written this way.

        for my $index (0 .. $#array) { # $#array is the numer of the highest e +lement. my @bits = split "\t", $array[$index]; }

        The first version is usually considered better though.


        Examine what is said, not who speaks.

        The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

        It's possible, of course, but whenever you're thinking of creating a gazillion separate variables dynamically, you're usually better off using an array or hash. I'm not sure exactly what you want to do, but are you thinking of something like this?
        foreach my $item (@data) { push @data_split, [split /\t/, $item]; }
        Then you will have an array of arrayrefs that contain each line's data split on tabs. And @data is kept intact for you.

        -- Mike

        --
        just,my${.02}

        I think you want something like the following inside your foreach loop. my ($name, $first_name, $tel, @rest) = split /\t/, $item; The array @rest is there as you are saying that you have a varying number of elements in each $item. Another alternative might be to just specify all possible elements and then check later if the variables are defined. Like this
        my ($name, $first_name, $tel, $address, $email, $last_field) = split / +\t/, $item; if (defined $last_field) { # do something }

        -- Hofmator

      You're calling split() in a void context, so whatever returned values it may be generating are just being discarded.

      Actually, no: the values are saved in @_. However, this usage of split is deprecated and will generate a warning when you use warnings or -w.

      — Arien

        You are correct. I thought it was only scalar context in which that happened, but it also apparently does it in void context as well. Good catch.

Re: using split on every element in an array
by VSarkiss (Monsignor) on Jan 17, 2003 at 15:32 UTC

    Not sure if this is exactly what you're looking for, but you could try something like this: my @new = map { split /\t/ } split /\n/, $data; Another way to do it is to split on either character: my @new = split /\n|\t/, $data;One of these will probably do what you want.

    Note, I haven't tested either one.

      I'd think to preserve lines you'd want to use a variation, like:
      my @new = map { [ split(/\t/) ] } split(/\n/, $data);
      This way you end up with an array of arrays, one for each line in the file.
Re: using split on every element in an array
by thezip (Vicar) on Jan 17, 2003 at 16:02 UTC
    If you're reading from a file, you can also read a single line at-a-time (instead of reading it _all_ and then splitting on the newlines), as in:
    open(FH, $filename) or die qq(Could not open file "$filename" for read +ing.\n); while(<FH>) { # my $line = $_; # my @arr = split(\t/, $line); # -or- my @arr = split(/\t/); # split defaults to $_ # process @arr values for a single line # ... } close FH;
    Where do you want *them* to go today?
Re: using split on every element in an array
by OM_Zen (Scribe) on Jan 17, 2003 at 19:58 UTC
    Hi,

    while(<fname>){ chomp; @data = split(/\\t/); print "[$_]\n"; map{print "[$_]\n"}@data; }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-04-20 03:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found