in reply to Find unique elements from multiple arrays

my @new = do{ my %seen; grep !$seen{$_}++, @a, @b, @c, @d; };

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: How to connect more arrays to a new array
by Abigail-II (Bishop) on Apr 28, 2003 at 06:22 UTC
    Ah, the solution from the FAQ. Unfortunally, the FAQ is wrong. Here's one array where the FAQ solution will give the wrong answer:
    @a = (undef, "");

    Ooops. The FAQ assumes the values map to unique strings. But that isn't true, the undefined value maps to an empty string. And then I haven't shown examples with references, tied variables or objects with overloaded stringification that all can cause the FAQ solution to give the wrong results.

    Abigail

      The problem is how to define equity once you start slinging around tied or overloaded objects. By equal value, by equal reference, or by entirely different semantics? It's a question with very individual replies depending on the situation, and there can't be a universal solution. As for the undef, which is actually a common case, you are right, I had forgotten about that, even though I've fixed it before.
      my @new = do{ my (%seen, $seen_undef); grep defined ? !$seen{$_}++ : !$seen_undef++, @a, @b, @c, @d; };

      Makeshifts last the longest.

      Perhaps a solution would be to use the values instead of the keys, but this means that all the data is copied about again, and so is highly unlikely to be the most efficient approach.

      my @new = do{local %h; @h{@a,@b,@c,@d} = (@a,@b,@c,@d); values %h};
      Adapted from BrowserUk's code

      --
      integral, resident of freenode's #perl
      
        That doesn't solve the problem at all. It fails for exactly the same reason:
        $ perl -le '@a = (undef, ""); @u = do {@h {@a} = @a; values %h}; print + scalar @u' 1 $

        Abigail