miketosh has asked for the wisdom of the Perl Monks concerning the following question:

I have two array refs, and I'd like back an array ref of the unique values in the two. My problem is I can't seem to figure out how to return a reference to keys %hash from my function.

Here is what I have:
sub unique { my @refs = @_; my %files = (); foreach my $ref (@refs) { $files{$_}++ foreach (@$ref); } my @arr = keys %files; return \@arr; }

I'd like to simplify the last two lines so that I don't need to declare a new array. (I'm using Perl 5.005_03) Any other suggestions for improvement are welcome.

Replies are listed 'Best First'.
Re: Return reference to hash keys
by kennethk (Abbot) on Nov 30, 2010 at 14:13 UTC

      Thanks! That is exactly what I needed. I didn't know the difference between a LIST and an ARRAY. I guess I still need to learn about it, but your solution for an anonymous array reference is exactly what I was looking for.

      Thanks a million.

      Here is my final code, for what it is worth. Yes, I needed to reinvent the wheel for portability, since getting List::MoreUtils is not an option...
      sub compare { my @refs = @_; my ($all, $inter, $diff); my %files; foreach my $ref (@refs) { foreach (@$ref) { $files{$_}++; } } $all = [ keys %files ]; foreach my $e (@$all) { push @{ $files{$e} > 1 ? $inter : $diff }, $e; } return ($all, $inter, $diff); }
        The difference between a list and an array is discussed a bit in perldata. The short, oversimplified version of it is that lists are values and arrays are variables.

        Regarding not using List::MoreUtils, Yes, even you can use CPAN should have an on-point discussion for consideration.

Re: Return reference to hash keys
by Limbic~Region (Chancellor) on Nov 30, 2010 at 14:14 UTC
    miketosh,
    There is a module that does this for you (List::MoreUtils). It is also a FAQ. The fact that you want a reference back is an implementation detail. If I were doing it and since order doesn't seem to matter, I would probably do something like:
    sub uniq { my %uniq; @uniq{map @$_, @_} = (); return [ keys %uniq ]; }

    Update: This code is untested. I modified it to account for passing in array refs instead of arrays.

    Cheers - L~R

OT Re: Return reference to hash keys
by ww (Archbishop) on Nov 30, 2010 at 14:15 UTC

    "I'm using Perl 5.005_03"

    I didn't know 5.005 had been ported to the steam-powered, gear-driven Univacs.   :-)

    Seriously, that was released in the last century (1999, I think). You might be well served by updating to the latest version available for your architecture.

      That would require administrative privileges on a processor used by hundreds of people for software development on many different programs. Upgrading is out of the question. It would require an Engineering Analysis, and a likely upgrade of many many scripts, costing our customers in excess of a few hundred thousand dollars. Something tells me that they wouldn't go for that.

      The good news is that we are upgrading to the newfangled AIX 5, which comes with a fancy-dancy Perl 5.8.3. It should take no more than 3 more years.