Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

How to read each line of a file into a nested array

by opolat (Novice)
on Jun 18, 2002 at 09:37 UTC ( [id://175316]=perlquestion: print w/replies, xml ) Need Help??

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

I have a partially sorted NASTRAN output file (NASTRAN is a finete element analysis software). I would like to read each line of the NASTRAN file into an array first. Each line contains 9 numbers seperated by white space. After reading each line I would like to put the first number of each line into a new nested array as a column and put the line which this number belongs to as a string into same nested array as the second column. Example:

1 2 3 4 5

10 20 30 40 50

200 100 300 2 1

new nested array will be

array(0,0) = 1 array(0,1) = '1 2 3 4 5'

array(1,0) = 10 array(1,1) = '10 20 30 40 50'

array(2,0) = 200 array(2,1) = '200 100 300 2 1'

Is this possible, can anybody help me???

  • Comment on How to read each line of a file into a nested array

Replies are listed 'Best First'.
Re: How to read each line of a file into a nested array
by crazyinsomniac (Prior) on Jun 18, 2002 at 09:52 UTC
    Yes. I will only offer reading material, as this truly is basic.

    To learn about arrays, and more importantly, why there are no true two dimensional arrays, please read perldata, perlref, perllol, and perldsc. You can skim through the last two (for now), but basically you need to read perlref cause all an AoA (Array of Arrays) is, is an Array of Array references, and you'll need to know all about references.

    Second, you'll need to visit your local documentation and read perlfunc, and take a good look at the function split (you'll probably wanna split on whitespace).

    That will get you to the point where you can manipulate the data, and populate your data structure as you wish (your AoA).

    If you don't know how to open a file, well it's back to perlfunc, and in this case, you're looking for open.

    If that is truly the case, you're best off reading perlfaq first, and investing in a book.

    If at any point you need further guidance into wading through the documentation, or if you simply don't know all the vast perl resources that are available to you, How to RTFM covers pretty much all of them.

     
    ______crazyinsomniac_____________________________
    Of all the things I've lost, I miss my mind the most.
    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Re: How to read each line of a file into a nested array
by jmcnamara (Monsignor) on Jun 18, 2002 at 10:10 UTC

    Ah, Nastran.

    Unless the data is sequential and non-sparse a hash would be better suited for this than an array.

    The following is a simple example to get you started:

    #!/usr/bin/perl -w use strict; my %hash; while (<DATA>) { chomp; next unless /\S/; # Skip blank lines /(\d+)/; # Match the first number $hash{$1} = $_; } for my $key (sort {$a <=> $b} keys %hash) { print $key, "\t", $hash{$key}, "\n"; } # Prints: # 1 1 2 3 4 5 # 10 10 20 30 40 50 # 200 200 100 300 2 1 __DATA__ 1 2 3 4 5 10 20 30 40 50 200 100 300 2 1

    You might also wish to split the data on each line and store it as an array ref in the hash. Have a look at the perldsc manpage for more information.

    --
    John.

Re: How to read each line of a file into a nested array
by flounder99 (Friar) on Jun 18, 2002 at 17:06 UTC
    Short answer:
    001 use strict; 002 my @array; 003 open (INFILE, "<filename") or die "could not open file"; 004 foreach (<INFILE>) { 005 chomp; 006 push @array, [m/(\d+)/, $_]; 007 } 008 close INFILE;

    Line by line explaination:

    Line 1: rule #1 always use strict it will save you hours in the long run.

    Line 2: Create a place to put our answers

    Line 3: open your data file INFILE is now the file handle for your data file. Relplace "filename" with the name of your file. It is good practice to always check the results of an open open will return a false value if it fails and a true value if it suceeds the right side of the or will never happen if it suceeds but we will die if it fails.

    Line 4: The diamond operator  <> reads one line from INFILE and sets the value of $_ to that string.

    Line 5: chomp the newline off the end of $_

    Line 6: Line noise? Let's break it down. push @array, will add whatever comes after the comma to the end of @array, "push" them on to the end. What is it pushing? Well the square brackets [] will turn whatever is inside of them into an anonymous array. This anonymous array will be push onto the end of @array. So Line 6 could be rewritten as

    $_ =~ m/(\d+)/; #set $1 to the first group of digits push @array, [$1, $_];
    or
    $_ =~ m/(\d+)/; my @subarray = ($1, $_); push @array, [@subarray];
    or even
    $_ =~ m/(\d+)/; my @subarray = ($1, $_); push @array, \@subarray;
    etc., etc., etc. TMTOWTDI

    Line 7: End of for loop

    Line 8: close the file

    Anyway,
    $array[0][0] will be "1"
    $array[0][1] will be "1 2 3 4 5"
    $array[1][0] will be "10"
    $array[1][1] will be "10 20 30 40 50"
    $array[2][0] will be "200"
    $array[2][1] will be "200 100 300 2 1"

    --

    flounder

      One more quick question ! If my NASTRAN output file was something like this:

      1 2 3 4 5

      1 20 30 40 50

      1 9 3 3 6

      4 6 7 9 0

      4 4 8 90 8

      4 5 2 7 20

      9 5 2 7 20

      9 20 30 40 50

      9 4 8 90 8

      The start of each line (The first number) represent an element ID. Would it possible to create a hashes of nested arrays where each element ID is the key for the created nested array. I know it does not make sense, but I need a seperate nested array for each element ID (start of each line) so that I can sort it later on based on a chosen column and print it. I have to get the all the lines that starts with first element put them in a nested array in a way which is described in the first message and later create a hash where the key is the element ID and points to a nested array which has all the information about that particular element. Basically: Element ID (key for the hash) = 1 points to a nested array of

      1 '1 2 3 4 5'

      1 '1 20 30 40 50'

      1 '1 9 3 3 6'

      Element ID = (key for the hash) = 4 points to a nested array

      4 '4 6 7 9 0'

      4 '4 4 8 90 8'

      4 '4 5 2 7 20'

      Element ID = (key for the hash) = 9 points to a nested array

      9 '9 5 2 7 20'

      9 '9 20 30 40 50'

      9 '9 4 8 90 8'

      I am not sure if this is the best way of doing it but I can not think of any other way. Any Help will be appreciated. Thanks a lot.

      Thanks flounder99, it works!, and thanks for the detailed explanation!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (9)
As of 2024-04-18 13:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found