in reply to Deciding unique elements of an array

I have an array that has multiple entries of the same element in it. I want to make a new array with just the unique elements in it. How can this be done?

Pretty much every time you see the word "unique" in a problem, you want a hash. For this, I'd take a two-pass approach: tally the elements of the array, then pick out the unique ones. So:

my %elem_count = (); for my $elem (@array) { $elem_count{$elem}++; } my @uniques = (); for my $elem (keys %elem_count) { push @uniques, $elem if $elem_count{$elem} == 1; }

So (to be brutally obvious) we're storing the number of times we see each element in the hash %elem_count, then going through %elem_count key by key, picking out the ones that have a count of 1. (Of course, you can do the first bit at the same time as you're inserting elements in the array, which may or may not be practical.)

As for your second question, I confess I don't really see the problem. Unless you've been mucking around with $/, $_ will contain the line you just read in at every pass through the while.

--
:wq

Replies are listed 'Best First'.
Re: Re: Deciding unique elements of an array
by Hofmator (Curate) on Nov 15, 2001 at 19:06 UTC

    You have a strange definition of unique :) ... your code removes any entries which don't occur exactly once, try for example this:

    my @array = qw/one one two/; # your algorithm print @uniques; # prints 'two' # and I would expect 'onetwo'

    So changing that and putting it a bit shorter:

    my %count = (); my @uniques = grep {! $count{$_}++} @array;

    ... and btw this should be in the FAQs somewhere.

    -- Hofmator

      You have a strange definition of unique :) ... your code removes any entries which don't occur exactly once

      Oh, I don't know, I like my definition. :-) I read (misread?) the question as "pick out the elements that occur just once" rather than "make a copy of the list with duplicate elements removed".

      ... and btw this should be in the FAQs somewhere.

      I believe it is, as mentioned in an earlier response.

      --
      :wq