> Steve Bertrand wrote:
>> > Steve Bertrand wrote:
>> > > I got it...
>> > >
>> > > for my $item (@clean) {
>> > >         if (! grep ($_ eq $item, @array)) {
>> > >                 push (@array, $item);
>> > >                 print "$item\n";
>> > >         }
>> > > }
>> >
>> > FWIW, this is a FAQ (see "perldoc -q duplicate"). If the array
>> > elements can be compared with string semantics (as you are doing
>> > here), the following will work:
>> >
>> >    my @array = do { my %seen; grep !$seen{$_}++, @clean };
>>
>> Thank you for the info...but pardon my ignorance. I'd just like to
>> understand what is happening there. Is grep adding to the array the
>> keys in the hash that have values that have not been incremented?
>
> Erm, sort of...
>
> grep() is a function that returns a list. Since it's the last
> expression
> evaluated in the do { } block, that list becomes the result assigned
> to
> @array.
>
> grep() takes an input list (the elements of @clean) and returns a list
> composed of each element from @clean for which the following
> expression is
> true:
>
>    !$seen{$_}++
>
> Within the expression $_ represents the current element of @clean
> being
> examined. What's happening is that the hash entry $seen{$_} is being
> incremented by one. The value of the expression is the hash entry
> $seen{$_}
> BEFORE incrementing.
>
> So, for any given string coming from @clean, the hash entry $seen{$_}
> will
> be undef the first time, and then 1 the second time, 2 the third time,
> and
> so on. The ! operator logically negates the value, so the entire
> expression
> returns the following pattern for a repeated series of the same value:
>
>    true, false, false, false, ...
>
> In other words, the expression is true only for the first occurence of
> each
> different entry in @clean. Since grep() only passes through the
> elements for
> which the expression is "true", only the first occurence of each
> different
> entry in @clean makes it into @array, thus "removing" the duplicates,
> QED.
>
> The do { } block is there because we need a temporary hash. The hash
> goes
> away at the end of the do { } block since we don't need it after
> grep() is
> finished.
>
> n.b. there's another way you can do this:
>
>    @array = do { my %h; @[EMAIL PROTECTED] = (); keys %h };
>
> or similarly,
>
>    @array = keys %{{map +($_, 1), @clean}};
>
> These do not preserve the order of the values in @clean however.

Absolutely incredible. Thank you for such a detailed and complete
response to my question. Not only was I able to understand, while
reading, I counted at least a dozen places currently where I can
actually use these techniques.

Your reply is graciously appreciated ;o)

Steve
>



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to