domm has asked for the wisdom of the Perl Monks concerning the following question:

Does anyone know of a CPAN-module that enables me to "merge" two data structures?

I.e., a wrapper around .=, push and %hash=(%hash,%newhash) that checks the data type of it's arguments and "pushes" the second onto the first, according to some rules. I am not looking for a way to overload .= et.al.

In fact, I've got a sub that does all this, but maybe this is allready on CPAN, allthough I couldn't find anything.

So, any pointers would be appreciated.

-- #!/usr/bin/perl for(ref bless{},just'another'perl'hacker){s-:+-$"-g&&print$_.$/}

Replies are listed 'Best First'.
Re: merge two simple data structures
by broquaint (Abbot) on Jul 15, 2002 at 10:34 UTC
    Would the grep function suffice for this? If not there's always the Hash::Merge which you could put a simple wrapper around. Failing the above 2 suggestions perhaps you could write and upload a module to CPAN which performs the function you describe.
    HTH

    _________
    broquaint

Re: merge two simple data structures
by Abigail-II (Bishop) on Jul 15, 2002 at 12:06 UTC
    The only way of doing so is to accept that the parameters (or at least the first) are passed as an explicite reference. There's no way to prototype a function in perl that takes either two scalars, or two arrays or two hashes as argument, without the arguments getting flatted into a single list.

    sub merge ($$) { die "Not the same references.\n" unless ref ($_ [0]) eq ref ($_ [1 +]); if ("" eq ref $_ [0]) { $_ [0] .= $_ [1]; } elsif ("ARRAY" eq ref $_ [0]) { push @{$_ [0]} => @{$_ [1]} } elsif ("HASH" eq ref $_ [0]) { @{$_ [0]} {keys %{$_ [1]}} = values %{$_ [1]}; } else { die "Cannot merge type ", ref $_ [0], "\n"; } }

    Abigail

Re: merge two simple data structures
by shotgunefx (Parson) on Jul 15, 2002 at 11:18 UTC
    I don't know if you will find a good generic choice. If you are going to merge to hashes, what do you do with duplicates? Replace one with the other? If so, what criteria? Maybe instead merge them into an anonymous array?

    Using a module seems like overkill. I'd stick to subs unless you want to be able to pull them apart afterwards in the same pieces they went in or have some other behavior like Tie::ShadowHash, etc.

    -Lee

    "To be civilized is to deny one's nature."
Re: merge two simple data structures
by Aristotle (Chancellor) on Jul 15, 2002 at 13:47 UTC
    Abigail-II provided the solution. What I do wonder about however is why you want to do so? I know I've wished for something similar sometimes in the past, but in retrospect I found that every single one of these times was due to a misguided approach. If you want to, maybe you could explain your reasoning and see if someone can't come up with a better approach to this.

    Makeshifts last the longest.

Re: merge two simple data structures
by cfreak (Chaplain) on Jul 15, 2002 at 15:04 UTC

    Interesting question... it seems to me that you could use the 'wantarray' function. Converting a hash to an array is pretty simple: something like this would do the trick. (untested)

    sub merge { if(wantarray) { return @_; } else { return join('',@_); } }

    Any hash you pass to it should auto-magically convert to an array and then back again so this should work:

    my %hash = merge(%hash1,%hash2);

    And then scalars or arrays should work to

    my @array = merge(@array1,@array2); my $scalar = merge($scalar1,$scalar2); # or like the push function (only you have to get the return value) my @array = merge(@array2,$scalar);

    Hope that helps

    Chris

    Lobster Aliens Are attacking the world!