package Hash::Work; # Several static functions to manipulate hash-arrays



our $VERSION='0.01';

# This class provides several static methods to manipulate hashes.
# Some of this methods you can also find in different modules, but
# I wanted to provide a simplier way to import that methods to a class.
#
# SYNOPSIS
# ========
#
#  # exports all functions
#  use Hash::Work ':all';
# 
#  # E.g. a specific function
#  use Hash::Work qw/merge_hashes/;
#
# LICENSE
# =======   
# You can redistribute it and/or modify it under the conditions of LGPL.
# 
# AUTHOR
# ======
# Andreas Hernitscheck  ahernit(AT)cpan.org 


use strict;
use 5.006; 

use vars qw(@ISA @EXPORT %EXPORT_TAGS $VERSION);

use Hash::Merge qw( merge );
use Clone qw/clone/;
use Exporter;

@ISA = qw(Exporter);



%EXPORT_TAGS = ( all => [qw( 
                                merge_hashes
                                copy_hash_values
                                first_arrays_to_hash
                                array_to_hash
                         )] );

Exporter::export_ok_tags('all'); 




# takes 2 hashes and merges them by using their keys to one hash.
# returns a hash or hashref, depending on the context call.
# It uses the Hash::Merge class.
sub merge_hashes{
my $a=shift;
my $b=shift;
my %ha;

    my $mergec = Hash::Merge->new();

    my $c = $mergec->merge( $a, $b );

    return wantarray ? %$c : $c;
}



# copy the hash values from first hash to the second.
sub copy_hash_values{ # void (\%from,\%to)
my $from=shift;
my $to=shift;


    foreach my $k (keys %$from){
        $to->{$k}=$from->{$k};
    }

}





# removes arrays from a hash recursively by
# taking first array entry. 
#
# example:
#
# input:
#
#     $VAR1 = {
#             'anode' => [
#                             {
#                             'name' => 'anything',
#                             'abc' => [
#                                         {
#                                             'foo' => [
#                                                         'text'
#                                                     ]
#                                         }
#                                         ]
#                             }
#                         ]
#             };
#
# output:
#
#     $VAR1 = {
#             'anode' => {
#                             'name' => 'anything',
#                             'abc' => {
#                                         'foo' => 'text'
#                                     }
#                         }
#             };
# 
#
# I use it to handle some results of XML::Simple, to flaten it.
#
sub first_arrays_to_hash{
    my $h = clone(shift);

    if ( ref($h) eq 'HASH' ){

        foreach my $k ( keys %$h ){
            my $node = $h->{$k};

            if ( ref($node) eq 'ARRAY' ){
                $h->{$k} = first_arrays_to_hash( $node->[0] ); # rewrite node
            }

            
        }

        
    }elsif ( ref($h) eq 'ARRAY' ){
		$h = first_arrays_to_hash($h->[0]);
	}
	


    return $h;
}





# Converts simply an array to a hash by using the array entries as
# key and a 1 as value. Returns context specific a reference to a hash
# or a hash.
sub array_to_hash { # \%hashref (@array|\@arrayref)
    my @array = @_ if ref @_ eq '';
    my $arrayref = shift if ref $_[0] eq 'ARRAY';
    my %returned_hash;

    if( defined $arrayref ) {
            foreach my $line_ref(@{ $arrayref }) {
                    $returned_hash{$line_ref} = 1;
            }
    } else {
            foreach my $line (@array) {
                    $returned_hash{$line} = 1;
            }
    }
    return wantarray ? %returned_hash : \%returned_hash;
}



	

1;
#################### pod generated by Pod::Autopod - keep this line to make pod updates possible ####################

=head1 NAME

Hash::Work - Several static functions to manipulate hash-arrays


=head1 SYNOPSIS


 # exports all functions
 use Hash::Work ':all';

 # E.g. a specific function
 use Hash::Work qw/merge_hashes/;



=head1 DESCRIPTION

This class provides several static methods to manipulate hashes.
Some of this methods you can also find in different modules, but
I wanted to provide a simplier way to import that methods to a class.



=head1 REQUIRES

L<Exporter> 

L<Clone> 

L<Hash::Merge> 

L<5.006> 


=head1 METHODS

=head2 array_to_hash

 my \%hashref = array_to_hash(@array | \@arrayref);

Converts simply an array to a hash by using the array entries as
key and a 1 as value. Returns context specific a reference to a hash
or a hash.


=head2 copy_hash_values

 copy_hash_values(\%from, \%to);

copy the hash values from first hash to the second.


=head2 first_arrays_to_hash

 first_arrays_to_hash();

removes arrays from a hash recursively by
taking first array entry.

example:

input:

    $VAR1 = {
            'anode' => [
                            {
                            'name' => 'anything',
                            'abc' => [
                                        {
                                            'foo' => [
                                                        'text'
                                                    ]
                                        }
                                        ]
                            }
                        ]
            };

output:

    $VAR1 = {
            'anode' => {
                            'name' => 'anything',
                            'abc' => {
                                        'foo' => 'text'
                                    }
                        }
            };


I use it to handle some results of XML::Simple, to flaten it.



=head2 merge_hashes

 merge_hashes();

takes 2 hashes and merges them by using their keys to one hash.
returns a hash or hashref, depending on the context call.
It uses the Hash::Merge class.



=head1 AUTHOR

Andreas Hernitscheck  ahernit(AT)cpan.org 


=head1 LICENSE

You can redistribute it and/or modify it under the conditions of LGPL.



=cut

