[comp.lang.perl] Need clarification of assoc. arrays

dave@aspect.UUCP (Dave Corcoran) (01/29/91)

printf("Hello world\n");

Why is does this script:

	perl -e '
		$keyword{"one"}="ONE";
		$keyword{"two"}="TWO";

		for $i (%keyword) {
			print $i;
		}'

yield

	twoTWOoneONE

and not 

	onetwo	

I am trying to print the indices and the contents of the array thus:

	for $i (%keyword) {
		printf "the index is %s; the contents are %s\n",$i,$keyword{$i};
	}

Please enlighten me, I'm using the perl 3.0 (I have not access to
the patch program).

-- 
David Corcoran		      -@@
uunet!aspect!dave	        ~
In a society where anything goes eventually everything will.

composer@chem.bu.edu (Jeff Kellem) (01/31/91)

In article <7457@aspect.UUCP> dave@aspect.UUCP (Dave Corcoran) writes:
>
>   Date: 28 Jan 91 22:09:25 GMT
>
>   printf("Hello world\n");

print 'Hello world\n';	# if (a tiny bit) quicker  ;-)

>   Why is does this script:
>
>	   perl -e '
>		   $keyword{"one"}="ONE";
>		   $keyword{"two"}="TWO";
>
>		   for $i (%keyword) {
>			   print $i;
>		   }'
>   yield
>	   twoTWOoneONE
>   and not 
>	   onetwo	

An associative array is stored as a LIST of

	( key, value, key, value, ... )

So, when you just access it as %keyword, you're getting a LIST of the above.
If you just want the keys (indices) of the assoc. array, do...

	for $i (keys %keyword) { ... }
or
	for $i (sort keys %keyword) { ... }

if you want to access the assoc. array sorted by the keys.  To access just the
values assoc. array, use `values':

	for $value (values %keyword) { ... }

or to access both key/value pairs from the assoc. array:

	while (($key, $value) = each %keyword) { ... }

Take a look at the man page entries for `keys', `values', and `each'.

>   I am trying to print the indices and the contents of the array thus:
>
>	   for $i (%keyword) {
>	      printf "the index is %s; the contents are %s\n",$i,$keyword{$i};
>	   }

So, this should be written as

	for $i (keys %keyword) {
	    print "the index is $i; the contents are $keyword{$i}\n";
	}

Use `print' instead of `printf' when you can; it is a tiny bit faster.

Hope that helps..Enjoy Perl!

			-jeff

Jeff Kellem
Internet: composer@chem.bu.edu

marc@athena.mit.edu (Marc Horowitz) (01/31/91)

|> So, this should be written as
|> 
|> 	for $i (keys %keyword) {
|> 	    print "the index is $i; the contents are $keyword{$i}\n";
|> 	}
|> 
|> Use `print' instead of `printf' when you can; it is a tiny bit faster.

Well, if speed is really a concern, you want to avoid interpolated
strings.  The fastest way to do that is

	for $i (keys %keyword) {
	    print 'the index is ',$i,'; the contents are ',$keyword{$i},"\n";
	}

I'm using '' assuming that perl will try to interpolate in "" strings
even if there is no interpolation to be done.  If perl is smarter
than that, great.  (Is it, Larry?)  Anyway, interpolation causes extra
copies which you don't need, although I admit, the interpolation form
is a lot nicer looking.

		Marc

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/31/91)

In article <1991Jan31.033851.19246@uvaarpa.Virginia.EDU> marc@mit.edu writes:
: I'm using '' assuming that perl will try to interpolate in "" strings
: even if there is no interpolation to be done.  If perl is smarter
: than that, great.  (Is it, Larry?)

Yes.  Even "\n" is considered a single-quoted string after it's compiled.

Larry

jdr@sloth.mlb.semi.harris.com (Jim Ray) (02/06/91)

Am I missing something?  I am wanting to use an associative array with
indicies being themselves part of an array ( array of strings ).

Something like this:

  $areacode{ $phone[0] } = $areacode { $phone[0] } + 1;

Where $phone[...] is an array of strings containing :
	713
	MAL

	etc.....  ie ... they can be text strings and number'd strings.

Is this possible?  ( I already tried printing it out %areacode with
		     negative results )



--
Jim Ray                                Harris Semiconductor
Internet:  jdr@semi.harris.com         PO Box 883   MS 62B-022
Phone:     (407) 729-5059              Melbourne, FL  32901

jdr@sloth.mlb.semi.harris.com (Jim Ray) (02/06/91)

In article <1991Feb5.233948.21013@mlb.semi.harris.com> jdr@sloth.mlb.semi.harris.com (Jim Ray) writes:
>Am I missing something?  I am wanting to use an associative array with
>indicies being themselves part of an array ( array of strings ).
>
>Something like this:
>
>  $areacode{ $phone[0] } = $areacode { $phone[0] } + 1;
>
>Where $phone[...] is an array of strings containing :
>	713
>	MAL
>
>	etc.....  ie ... they can be text strings and number'd strings.
>
>Is this possible?  ( I already tried printing it out %areacode with
>		     negative results )

Obviously, I didn't understand associative arrays.......  Now that I
do ( somewhat ), it is fairly obvious what the problem was -- I was
printing it out thus:  print " %areacode \n";  I should have used :

while (($number,$count) = each %areacode) {  print " $number =$count\n";}

Oh well.... I think I'll buy the book.

--
Jim Ray                                Harris Semiconductor
Internet:  jdr@semi.harris.com         PO Box 883   MS 62B-022
Phone:     (407) 729-5059              Melbourne, FL  32901