http://qs321.pair.com?node_id=514180


in reply to Re: lsearch for perl?
in thread lsearch for perl?

When you're using lists, ask yourself if it could be done more easily with a hash.
In my opinion, they address different problems. Arrays are an ordered set of things, hashes are an unordered set of associations. Sure, if you find yourself doing something like this:
my (@item, @color); while(<DATA>) { chomp; my($item, $color) = split(/,/); push @item, $item; push @color, $color; } for(my $i=0; $i < @item; $i++) { print "$item[$i] has color $color[$i]\n"; } __DATA__ apple,red orange,orange banana,yellow
then yes...use a hash. Don't try to shoehorn it, though.

thor

The only easy day was yesterday

Replies are listed 'Best First'.
Re^3: lsearch for perl?
by ikegami (Patriarch) on Dec 05, 2005 at 18:18 UTC

    While I agree that hashes wouldn't be too useful here (being unordered), I think of hashes as having three basic uses (not one):

    • Unordered set of associations (Notice the plural var name)
      my %user_passwds = ( joe => ..., jeff => ..., john => ..., );
    • Unordered set of properties (Notice the singular var name)
      my %user = ( id => 'joe', name => 'Joe', passwd => ..., home_dir => ..., );
    • Uniqueness constraint
      my %unique; ++$unique{$_} foreach @list; @list = keys %unique;
      I meant association in a looser sense than you mention above. For the first set, you're associating passwords with their respective users. In the second set, you're associating the given values with their type ("joe" is the "id" for this user). As for the uniqueness condition, I agree that it's useful, but not a hash's intended use. Incidentally, I think that the following loop uses less memory:
      my %unique; $unique{$_} = undef foreach @list; @list = keys %unique;
      due to the undef being shared amongst all of the keys of the hash. That may be an urban legend that I heard somewhere, though. ;)

      thor

      The only easy day was yesterday

        I'm pretty sure undef uses less mem, and it's probably a bit faster, but ++ allows you to check which items had duplicates. undef @unique{@list}; is actually fastest.
Re^3: lsearch for perl?
by aufflick (Deacon) on Dec 06, 2005 at 01:44 UTC
    Arrays have many uses and sometimes perl programmers can overuse hashes, but as an ex-Tcl programmer myself I can give the advice to:
    1. use hashes when you can
    2. when an array is appropriate, use foreach, map and grep. Some perl programmers might overuse map and grep, but when they are good they are VERY good!
    3. if you find yourself using an array index ask yourself why - there is almost always a better way in perl
    For the enlightenment of non-Tcl people, Tcl has only two types of data. Strings and lists. That's it. Even function calls are just a list where the first list value is the name (string) of a function (or proc) and the rest of the list values are the arguments (which may be, you guessed it, strings or lists).

    The lists aren't even very convenient, vis. lsearch.

    Don't think I'm bashing Tcl - it's very useful when you need a straightforward embeddable scripting language. You can even make it do very non-trivial things (vis. OpenACS) but it hurts.

    upvar anyone?