Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
User Journal

Journal blinder's Journal: Perl Question: Merging Arrays 13

Okay, my brain has turned to pudding. I can't seem to figure this particular problem out.

I am working on this perl script. la la la la la

and basically I have to lists (arrays) one array contains elements that must be deleted from the other array.

illustration:

@delete_me = qw(foo/bar whoey/bar la_la/bar);
@master_list = qw(foo/bar whoey/bar la_la/bar bar/foo/is/good/bar);

So basically I want to end up with a third array/list with just:

@diff = qw( bar/foo/is/good/bar );

I've looked at Alogrithm::Diff and Algorithm::merge -- and well, they don't seem to be produce what I want.

Please, I hope someone here can dislodge this brain cloud I'm suffering from. I *know* this is like the dumbest fucking problem EVAR, but nuthin's happenin upstairs today :)

This discussion has been archived. No new comments can be posted.

Perl Question: Merging Arrays

Comments Filter:
  • @union = @intersection = @difference = ();
    %count = ();
    foreach $element (@array1, @array2) { $count{$element}++ }
    foreach $element (keys %count) {
    push @union, $element;
    push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
    }


    From the perlfaq. Something more along what you'd need would be:


    foreach $element (@master, @onestoremove) {
    $hash{$element}++;
    }
    foreach $key (keys %hash) {
    push(@newlist,$key) if $hash{key} == 1;
    }


    I *think* that should do it
  • @diff=();
    foreach $i (@master_list) {
    $match = 0;
    foreach $j (@delete_me) {
    if ( $i eq $j ) {
    $match = 1;
    last;
    }
    }
    if ( ! $match ) {
    push @diff, $i;
    }
    }

    Not elegant, but functional...

    ----Extra words lameness filter defeeter...:-/----
  • @delete_me = qw (a b c d f);
    @master_list = qw (q w e r t y u i o p a s d f g h j k l z x c v b n m);

    foreach $compare (@master_list)
    {
    $flag = 0;
    foreach $remove (@delete_me)
    {
    if ($remove eq $compare)
    {
    $flag = 1;
    }
    }
    if ($flag != 1)
    {
    push (@difflist, $compare);
    }
    }

    print "@difflist";
  • @delete_me = qw(foo/bar whoey/bar la_la/bar);
    @master_list = qw(foo/bar whoey/bar la_la/bar bar/foo/is/good/bar);
    @diff = do {
    my %things = map { $_, 1 } @master_list;
    delete @things{@delete_me};
    sort keys %things;
    };
    • heh, well this is cool. one of the perl masters coming across my lil je :)

      i like this -- i'll prolly go ahead and put this bit in there... i mean, i'd be crazy not to right??? ;-P

    • Hmmmm ... that's roughly the approach I was going to recommend :( Though I don't think it would have been as concise.

      So I'll propose something slightly different - instead of using a hash like a set, just use the Set::Scalar module from CPAN:

      use Set::Scalar;

      my @delete_me = qw(foo/bar whoey/bar la_la/bar);
      my @master_list = qw(foo/bar whoey/bar la_la/bar bar/foo/is/good/bar);

      my $delete_set = Set::Scalar->new(@delete_me);
      my $master_set = Set::Scalar->new(@master_list);
      my $diff_set = $master_set - $de
  • Still messing about with file paths I see :)

    My humble suggestion is to use Set::Scalar; [slashdot.org] It's very useful for all kinds of set operations, and it overloads operators like "+" and "-" so you can express yourself *very* succinctly. Have a look at the Set::Scalar CPAN page [cpan.org].
    • Still messing about with file paths I see :)

      yeah... just when I thought the program was good and people started using it... someone comes around and says "yeah, this is great, but can you reverse how it works?"

      And with 97 other things going... i had to hack this thing to do the complete oposite it originally did :)

      I haven't seen Set::Scalar, but it looks pretty interesting. I'll hafta take a look-see

Nobody said computers were going to be polite.

Working...