[comp.lang.perl] #elements in assoc array / array in scalar context

tell@oscar.cs.unc.edu (07/30/90)

What is the recommended way to find out how many elements are in an
associative array?  I don't see any method that looks particularly
efficient.

Here's some playing around I did on some real code:

#
  DB<3> s
read_libdata(289):              $nvalues = keys(%needvalues);
  DB<3> s
read_libdata(291):              while($libfile = pop(@libfiles) && $nvalues) {
  DB<3> p $nvalues
      
#
# Hmmm. $nvalues isn't set to anything useful.  How do we find how many
# items we're looking for?
# First he takes a stab in the dark:
#
  DB<5> p $#keys(%needvalues)
syntax error in file (eval) at line 1, next 2 tokens "$#keys("

  DB<6> p $#(keys(%needvalues))
syntax error in file (eval) at line 1, next 2 tokens "$#("

# Then he remembers the manual page:
#     If you evaluate an array in a scalar context, it returns the
#     length of the array.  The following is always true:
#
#          @whatever == $#whatever - $[ + 1;
# and tries to "force a scalar (or numeric) context"
#
  DB<8> p keys(%needvalues) + 0
0
  DB<9> p (keys(%needvalues)) + 0
0
  DB<10> p 0+keys(%needvalues)
0
#
# This works, but copying that big array around seems inefficient.
# or is the optimizer that good?
#
  DB<11> @foo = keys(%needvalues); print $#foo
5
#
# Just make sure that our test data is really ther
#
  DB<12> p join(';', keys(%needvalues))
CRYSTAL;74LS04;74HCT573;74LS08;8052;LED
		  

So, how about making keys(%foo) return the number of elements in foo
if evaluated in a scalar context?    What does it produce in this context
now?

If I'm missing somthing, (and I probably am) please let me know.



$Header: perly.c,v 3.0.1.5 90/03/27 16:20:57 lwall Locked $
Patch level: 18

Copyright (c) 1989, 1990, Larry Wall

Perl may be copied only under the terms of the GNU General Public License,
a copy of which can be found with the Perl 3.0 distribution kit.

--------------------------------------------------------------------
Steve Tell      e-mail: tell@wsmail.cs.unc.edu usmail:  #5L Estes Park apts
CS Grad Student, UNC Chapel Hill.                       Carrboro NC 27510
Former chief engineer, Duke Union Community Television, Durham, NC.

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (07/31/90)

In article <15429@thorin.cs.unc.edu> tell@oscar.cs.unc.edu () writes:
: 
: What is the recommended way to find out how many elements are in an
: associative array?  I don't see any method that looks particularly
: efficient.

There isn't any efficient way.  You can find out how many buckets in the
hash table are in use, which will give you an approximation for non-dbm
files, since most filled buckets will only have a single entry.  I suppose
I could keep a count, but I don't.  And such a count wouldn't work on dbm
files anyway.  Currently, in a scalar context, %array returns the
filled_buckets/allocated_buckets ratio.  That's 0/4 on an empty associative
array.  After the next patch, it will return 0 if no buckets are filled,
so you can at least use %array as a boolean.

Given the problem with dbm files, I don't anticipate changing Perl to
keep track.  If you want the count, then $count++.

Larry