home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / perl / 5372 < prev    next >
Encoding:
Text File  |  1992-08-18  |  4.4 KB  |  124 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cs.utexas.edu!convex!convex!tchrist
  3. From: Tom Christiansen <tchrist@convex.COM>
  4. Subject: Re: What's the best idiom for storing keyed records?
  5. Originator: tchrist@pixel.convex.com
  6. Sender: usenet@news.eng.convex.com (news access account)
  7. Message-ID: <1992Aug19.004516.12825@news.eng.convex.com>
  8. Date: Wed, 19 Aug 1992 00:45:16 GMT
  9. Reply-To: tchrist@convex.COM (Tom Christiansen)
  10. References: <l90cclINNrjo@jethro.Corp.Sun.COM>
  11. Nntp-Posting-Host: pixel.convex.com
  12. Organization: CONVEX Realtime Development, Colorado Springs, CO
  13. X-Disclaimer: This message was written by a user at CONVEX Computer
  14.               Corp. The opinions expressed are those of the user and
  15.               not necessarily those of CONVEX.
  16. Lines: 106
  17.  
  18. From the keyboard of tmhoff@oogoody.Corp.Sun.COM:
  19. :
  20. :How in the heck do I store a list in an associative array?
  21. :I want to store a datbase record in an array, but it seems
  22. :an associative array only stores strings. This must be
  23. :a common problem. I would like to see how others have solved it.
  24. :
  25. :I can think of creating an array for every record field, but this
  26. :seems crude.
  27.  
  28. I know, I've been  remiss about posting the FAQ, but #17 discusses
  29. this.  You can
  30.  
  31.     a) store the array as "@array" and resplit it each time.
  32.     b) store the array as its name, "array", and eval "\@$name"
  33.        to get at it.
  34.     c) store the array as a pointer to its stab entry, *array,
  35.     and local(*array) = $table{$entry} to get at it.
  36.  
  37. --tom
  38.  
  39. 17) How can I make an array of arrays or other recursive data types?
  40.  
  41.     Remember that Perl isn't about nested data structures, but rather flat
  42.     ones, so if you're trying to do this, you may be going about it the
  43.     wrong way.  You might try parallel arrays with common subscripts.
  44.  
  45.     But if you're bound and determined, you can use the multi-dimensional
  46.     array emulation of $a{'x','y','z'}, or you can make an array of names
  47.     of arrays and eval it.
  48.  
  49.     For example, if @name contains a list of names of arrays, you can 
  50.     get at a the j-th element of the i-th array like so:
  51.  
  52.     $ary = $name[$i];
  53.     $val = eval "\$$ary[$j]";
  54.  
  55.     or in one line
  56.  
  57.     $val = eval "\$$name[$i][\$j]";
  58.  
  59.     You could also use the type-globbing syntax to make an array of *name
  60.     values, which will be more efficient than eval.  Here @name hold
  61.     a list of pointers, which we'll have to dereference through a temporary
  62.     variable.
  63.  
  64.     For example:
  65.  
  66.     { local(*ary) = $name[$i]; $val = $ary[$j]; }
  67.  
  68.     In fact, you can use this method to make arbitrarily nested data
  69.     structures.  You really have to want to do this kind of thing
  70.     badly to go this far, however, as it is notationally cumbersome.
  71.  
  72.     Let's assume you just simply *have* to have an array of arrays of
  73.     arrays.  What you do is make an array of pointers to arrays of
  74.     pointers, where pointers are *name values described above.  You
  75.     initialize the outermost array normally, and then you build up your
  76.     pointers from there.  For example:
  77.  
  78.     @w = ( 'ww' .. 'xx' );
  79.     @x = ( 'xx' .. 'yy' );
  80.     @y = ( 'yy' .. 'zz' );
  81.     @z = ( 'zz' .. 'zzz' );
  82.  
  83.     @ww = reverse @w;
  84.     @xx = reverse @x;
  85.     @yy = reverse @y;
  86.     @zz = reverse @z;
  87.  
  88.     Now make a couple of array of pointers to these:
  89.  
  90.     @A = ( *w, *x, *y, *z );
  91.     @B = ( *ww, *xx, *yy, *zz );
  92.  
  93.     And finally make an array of pointers to these arrays:
  94.  
  95.     @AAA = ( *A, *B );
  96.  
  97.     To access an element, such as AAA[i][j][k], you must do this:
  98.  
  99.     local(*foo) = $AAA[$i];
  100.     local(*bar) = $foo[$j];
  101.     $answer = $bar[$k];
  102.  
  103.     Similar manipulations on associative arrays are also feasible.
  104.  
  105.     You could take a look at recurse.pl package posted by Felix Lee
  106.     <flee@cs.psu.edu>, which lets you simulate vectors and tables (lists and
  107.     associative arrays) by using type glob references and some pretty serious
  108.     wizardry.
  109.  
  110.     In C, you're used to creating recursive datatypes for operations
  111.     like recursive decent parsing or tree traversal.  In Perl, these
  112.     algorithms are best implemented using associative arrays.  Take an
  113.     array called %parent, and build up pointers such that $parent{$person}
  114.     is the name of that person's parent.  Make sure you remember that
  115.     $parent{'adam'} is 'adam'. :-) With a little care, this approach can
  116.     be used to implement general graph traversal algorithms as well.
  117.  
  118.  
  119. -- 
  120.     Tom Christiansen      tchrist@convex.com      convex!tchrist
  121.  
  122.     signal(i, SIG_DFL); /* crunch, crunch, crunch */
  123.         --Larry Wall in doarg.c from the perl source code
  124.