On Jan 31, Robin Sheat said:

>> > @a=([1,2,3],[5,5,5],[9,8,7]);
>> > @b=([5,5,5],[1,2,3]);
>> > @[EMAIL PROTECTED]@b;

>#####
># subArray - takes two array references, and subtracts any instances
># of the arrays in the second one from the first one. Returns the new list.
>sub subArray {
>    my @a = @{ shift() };
>    my @b = @{ shift() };
>    my @c;
>  OUTER: foreach my $outer (@a) {
>    INNER: foreach my $inner (@b) {
>        next OUTER if ($outer == $inner);
>    }
>      push @c, $outer;
>  }
>    return @c;
>}

Well, that only works if $a[0] is [1,2,3] and $b[1] is $a[0] -- that is,
the EXACT SAME reference.  It won't work if $b[1] is its own [1,2,3].

The simplest way to do this type of thing is to use a hash.

  sub array_diff {
    my ($first, $second) = @_;
    my %diff = map { "@$_" => 1 } @$second;
    return [ map !$diff{"@$_"}, @$first ];
  }

This builds a hash of the elements to subtract, and then it goes through
the elements of the set being subtracted FROM, and returns only those
elements NOT in the subtract-me hash.

It might look convoluted, but it's efficient.  It also prevents you from
doing the icky

  for this (set a) {
    for that (set b) {
      compare this and that
    }
  }

-- 
Jeff "japhy" Pinyan      [EMAIL PROTECTED]      http://www.pobox.com/~japhy/
RPI Acacia brother #734   http://www.perlmonks.org/   http://www.cpan.org/
<stu> what does y/// stand for?  <tenderpuss> why, yansliterate of course.
[  I'm looking for programming work.  If you like my work, let me know.  ]


-- 
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