in reply to Non-fixed data in record

Calling this entire fragment of data a 'block,' just to put a name to it, and presuming for the moment that the string 'PCSPLMNCallDataRecord' identifies the beginning of every such block of data, and further that 'mSTerminating' is a label (say, like its type) that could be different in each such block, I might write something like this to read it into a perl data structure:
my %PCSPLMNCallDataRecords; my $type_name; # type of the block we're reading my $block = undef; # place for block values while ( <> ) { # get each line somehow chomp; # no leading spaces means new block if ( /^PCSPLMNCallDataRecord/ ) { $type_name = undef; # next we expect a type name $block = undef; } # 3 leading spaces signals 'type' of block follows elsif ( /^\s{3}(\S.*)\s+$/ ) { next if ( $typename || $block ); # before we're ready $type_name = $1; # (e.g., 'mSTerminating') $block = {}; # next we expect data } # six leading spaces indicates data line elsif ( /^\s{6}(\S+)\s+(.+)\s*$/ ) { next if (! $typename || ! $block ); # before we're ready # lefthand column is the 'property' name. after first whitespace, # rest is data with trailing whitespace trimmed my ($key, $val) = ($1, $2); # first line in this block if ( scalar keys %$block == 0 ) { # if we don't already have an array create for this type, create + one now $PCSPLMNCallDataRecords{$type_name} = [] if not exists $PCSPLMNC +allDataRecords{$type_name}; # no values added yet, add hashref to array for this type only f +or first line push @{$PCSPLMNCallDataRecords{$type_name}}, $block; } $block->{$key} = $val; # add data to block (e.g., ' +callIdentificationNumber' => "2487067'D") } } # now you have the following structure in %PCSPLMNCallDataRecords: %PCSPLMNCallDataRecords = ( 'mSTerminating' => [ # array of 'mSTermina +ting' records { callIdentificationNumber => '2487067\'D', relatedCallNumber => '2487060\'D', recordSequenceNumber => '7410342\'D', exchangeIdentity => '"MAPP01E 01178 +02"\'S', mSCIdentification => '1119207079800F +\'TBCD', cellIDForFirstCellCalled => # etc ... }, { #... next mSTerminating record ... } ], 'mSOtherType' => [ array of 'mSOtherType' records, . +.. ] ); # an array of hashes with all of the 'mSTerminating' records: my @mSTerminating = @{$PCSPLMNCallDataRecords{mSTerminating}}; # the first 'mSTerminating' record in the array my %mSTerminating = %{$mSTerminating[0]}; # OR my %mSTerminating = %{$PCSPLMNCallDataRecords{mSTerminating}[0]};
Hope this helps ...

dmm

Just call me the Anti-Gates ...

Replies are listed 'Best First'.
Re: Re: Non-fixed data in record
by brassmon_k (Sexton) on Aug 31, 2001 at 22:30 UTC
    Wow,

    You're good! I mean, I understand it sort of. OK, you interpretted what I said exactly the righ way. That "PCSPLMNCallDataRecords" is at the top of every record block and then it is immediately followed by a subheading such as: mSTerminating, mSOriginating, transit, and like 3 others and everything below that are data lines that can be in different positions by 3 to 4 lines or more.

    I know you understand the question and posted a good answer but I have to understand the answer. What ever happened to 2+2=4. Wow, see that's why I have a hard time with hashes and arrays.
    The Brassmon_k
      brassmon_k ... Instead of starting with something as complex as your problem seems to be, why not start with something really simple and actually understand how Perl does multi-level data structures? You seem to want to eat your cake and have it, too.

      Perl understanding does not come very quickly, nor very easily. You have to be willing to work at it, just like anything else. Perl has a very deceiptfully easy learning curve, but it still has all the complexities of a C or a LISP.

      Another thing, and this is much more nitpicky - I would never classify someone who didn't understand multi-level data structures as intermediate in any language, especially not Perl. Look at it as your graduation-from-beginner test. You don't even need to understand how references work (though it helps, in the long run). Look back at my answer and try to understand it.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Vote paco for President!

      Thanks for the compliment. I see what you mean, though. What seemed to me to be a fairly simple deconstruction of the data turns into a fairly complex multilevel perl data structure.

      The trick to understanding these (at least what worked for me) is to realize that arrays (and hashes) can only store scalars, not other arrays (or hashes).

      Conveniently enough, references to arrays (or hashes) ARE scalars. So rather than an array of hashes (or hash of arrays, or whatever), you can have an array of hashrefs (or a hash of arrayrefs, etc.).

      Looking at your data, the first thing that struck me (as it apparently did to several other respondents) was that the lines below 'mSTerminating' appeared to suggest a hash (key/value pairs).

      Surmising (apparently correctly) that 'mSTerminating' was a type or descriptor name (i.e., that there might be more than one instance of it), I figured that there should be an array of references to the above hashes.

      Finally, we need a hash to associate a reference to this array with the string 'mSTerminating'.

      So the data itself suggests the structure: a hash which associates types (e.g., 'mSTerminating') with (a reference to) an array of instances, themselves represented by hashrefs.

      Hope this helps.

      dmm

      Just call me the Anti-Gates ...