Array subtraction, like sets

Ask a Question related to PERL Beginners, Design and Development.

  1. #1

    Default Array subtraction, like sets

    Hey there, what is a nice way of doing what this looks like it should
    do:

    @a=([1,2,3],[5,5,5],[9,8,7]);
    @b=([5,5,5],[1,2,3]);
    @c=@a-@b;

    and have @c == ([1,2,3]);

    Is there a good way of doing this? (I've tried the obvious things on the
    command line, to no avail). I could probably write a function for it
    without too much trouble, but it could get ugly :)

    cheers,
    --
    Robin <robin@kallisti.net.nz> JabberID: <eythian@jabber.org>

    Hostes alienigeni me abduxerunt. Qui annus est?

    PGP Key 0x776DB663 Fingerprint=DD10 5C62 1E29 A385 9866 0853 CD38 E07A 776D B663

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)

    iD8DBQFAGeYyzTjgendttmMRAlSoAKCMmy6fv/W82+h/ORChpit/GKZK8ACfSlkJ
    TvYssruqfKStKALHfWBAXXc=
    =VV9W
    -----END PGP SIGNATURE-----

    Robin Sheat Guest

  2. Similar Questions and Discussions

    1. Romanian Character Sets
      Help! We have a PDF with Romanian characters which views wonderfully. When we try to open it with Adobe Acrobat Professional v6.0 the characters come...
    2. Why did Photoshop CS quit suddenly in the middle of making sets? Action sets
      G4/450/dual/OSX33/1gigRAM/45gigHD/Photoshop CS Does anyone know why Photoshop CS quit suddenly in the middle of making Action sets, saying I had...
    3. CS quit suddenly in the middle of making Action sets Action sets,
      G4/450/dual/OSX33/1gigRAM/45gigHD/Photoshop CS Does anyone know why Photoshop CS quit suddenly in the middle of making Action sets, saying I had...
    4. merging found sets????
      Hi all I'm hoping you can help out... I've got 2 databases - each containg list of people going to various events one database is members...
    5. two sets of javascript?
      mello: I would need to see the code to comment. -- Murray --- ICQ 71997575 Team Macromedia Volunteer for Dreamweaver MX (If you *MUST* email...
  3. #2

    Default Re: Array subtraction, like sets

    >
    > Hey there, what is a nice way of doing what this looks like it should
    > do:
    >
    Going to need more info about what you think this looks like it should
    do, because I (and maybe others here) lack the math skills to get your
    answer, funny, I got [9,8,7].
    > @a=([1,2,3],[5,5,5],[9,8,7]);
    > @b=([5,5,5],[1,2,3]);
    > @c=@a-@b;
    >
    > and have @c == ([1,2,3]);
    >
    > Is there a good way of doing this? (I've tried the obvious things on the
    > command line, to no avail). I could probably write a function for it
    > without too much trouble, but it could get ugly :)
    >
    The obvious things are inside your head, my obvious thing would be to go
    immediately to CPAN and look for the formal name of whatever it is you
    are attempting, one (mediocre at best) guess would be to start at either:

    [url]http://search.cpan.org/~ulpfr/Math-Matrix-0.4/Matrix.pm[/url]

    Or,

    [url]http://search.cpan.org/modlist/Data_and_Data_Types/Math[/url]

    [url]http://danconia.org[/url]

    Wiggins D Anconia Guest

  4. #3

    Default Re: Array subtraction, like sets

    On Fri, Jan 30, 2004 at 07:48:35AM -0700, Wiggins d Anconia wrote:
    > Going to need more info about what you think this looks like it should
    > do, because I (and maybe others here) lack the math skills to get your
    > answer, funny, I got [9,8,7].
    Thats what I get for not profraedinng, the result should be:
    @c = [9,8,7]
    > > @a=([1,2,3],[5,5,5],[9,8,7]);
    > > @b=([5,5,5],[1,2,3]);
    > > @c=@a-@b;
    > The obvious things are inside your head, my obvious thing would be to go
    > immediately to CPAN and look for the formal name of whatever it is you
    > are attempting, one (mediocre at best) guess would be to start at either:
    Well, I ended up having to write a function, it wasn't quite as ugly as
    I thought (pasted below, for the benefit of others). However, if there
    was a better way, I'd like to know how :)

    Heres what I got (odd seeming indents courtisy of emacs):

    #####
    # 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;
    }


    --
    Robin <robin@kallisti.net.nz> JabberID: <eythian@jabber.org>

    Hostes alienigeni me abduxerunt. Qui annus est?

    PGP Key 0x776DB663 Fingerprint=DD10 5C62 1E29 A385 9866 0853 CD38 E07A 776D B663

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)

    iD8DBQFAGnRkzTjgendttmMRApZBAKCxRFa78IlAqZ82L6kySK 0MsY++WACfc4n+
    9chanrs3DIeguMx7ZKei66A=
    =eo/a
    -----END PGP SIGNATURE-----

    Robin Sheat Guest

  5. #4

    Default Re: Array subtraction, like sets

    On Jan 31, Robin Sheat said:
    >> > @a=([1,2,3],[5,5,5],[9,8,7]);
    >> > @b=([5,5,5],[1,2,3]);
    >> > @c=@a-@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]japhy@pobox.com[/email] [url]http://www.pobox.com/~japhy/[/url]
    RPI Acacia brother #734 [url]http://www.perlmonks.org/[/url] [url]http://www.cpan.org/[/url]
    <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. ]

    Jeff 'Japhy' Pinyan Guest

  6. #5

    Default RE: Array subtraction, like sets

    Robin Sheat wrote:
    > Hey there, what is a nice way of doing what this looks like it should
    > do:
    >
    > @a=([1,2,3],[5,5,5],[9,8,7]);
    > @b=([5,5,5],[1,2,3]);
    > @c=@a-@b;
    >
    > and have @c == ([1,2,3]);
    >
    > Is there a good way of doing this? (I've tried the obvious things on
    > the command line, to no avail). I could probably write a function for
    > it without too much trouble, but it could get ugly :)
    See perldoc -q 'How do I compute the difference of two arrays?'

    There are also numerous Set manipulation modules on CPAN. Try:

    [url]http://search.cpan.org/search?query=set%3A%3A&mode=module[/url]
    Bob Showalter Guest

  7. #6

    Default Re: Array subtraction, like sets

    On Fri, Jan 30, 2004 at 10:33:27AM -0500, Jeff 'japhy' Pinyan wrote:
    > 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].
    Hmm, right. Not so good. I had thought of that, and thought I tested it
    in that situation, but I can't reproduce those tests now, so obviously
    I messed something up. Your method looks somewhat nicer than mine,
    anyway, so I may steal that :)

    cheers,
    --
    Robin <robin@kallisti.net.nz> JabberID: <eythian@jabber.org>

    Hostes alienigeni me abduxerunt. Qui annus est?

    PGP Key 0x776DB663 Fingerprint=DD10 5C62 1E29 A385 9866 0853 CD38 E07A 776D B663

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)

    iD8DBQFAGwsZzTjgendttmMRAtV7AJ90d60DwE3y63iMKLilM3 BiyWH0YgCeLtKQ
    uDAwJx2Qs/rh6Zesz1Nmfq8=
    =8ZZF
    -----END PGP SIGNATURE-----

    Robin Sheat Guest

  8. #7

    Default Re: Array subtraction, like sets

    On Fri, Jan 30, 2004 at 10:33:27AM -0500, Jeff 'japhy' Pinyan wrote:
    > sub array_diff {
    > my ($first, $second) = @_;
    > my %diff = map { "@$_" => 1 } @$second;
    > return [ map !$diff{"@$_"}, @$first ];
    > }
    amended to:
    return [ grep !$diff{"@$_"}, @$first ];
    (for the benefit of anyone else looking at this), and it works a charm
    (with the really minor exception of being an array too deep, but that is
    easy fixed.)
    cheers,
    --
    Robin <robin@kallisti.net.nz> JabberID: <eythian@jabber.org>

    Hostes alienigeni me abduxerunt. Qui annus est?

    PGP Key 0x776DB663 Fingerprint=DD10 5C62 1E29 A385 9866 0853 CD38 E07A 776D B663

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)

    iD8DBQFAHHztzTjgendttmMRAgCFAJ47GyxvJRNmXLPFtJLNJb rex6D0bgCdENvn
    rQqVX5uehAixuMqr7QrZfRY=
    =p+7N
    -----END PGP SIGNATURE-----

    Robin Sheat Guest

  9. #8

    Default Re: Array subtraction, like sets

    On Feb 1, Robin Sheat said:
    >On Fri, Jan 30, 2004 at 10:33:27AM -0500, Jeff 'japhy' Pinyan wrote:
    >> sub array_diff {
    >> my ($first, $second) = @_;
    >> my %diff = map { "@$_" => 1 } @$second;
    >> return [ map !$diff{"@$_"}, @$first ];
    >> }
    >amended to:
    > return [ grep !$diff{"@$_"}, @$first ];
    >(for the benefit of anyone else looking at this), and it works a charm
    >(with the really minor exception of being an array too deep, but that is
    >easy fixed.)
    Thanks for that fix. I wrote 'map' once, I wrote it twice. Silly
    mistake.

    As far as it being an array too deep, I did that because it takes two
    array refs of array refs as arguments, so I made it return an array ref of
    array refs.

    --
    Jeff "japhy" Pinyan [email]japhy@pobox.com[/email] [url]http://www.pobox.com/~japhy/[/url]
    RPI Acacia brother #734 [url]http://www.perlmonks.org/[/url] [url]http://www.cpan.org/[/url]
    <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. ]

    Jeff 'Japhy' Pinyan Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139