合并其中包含哈希的perl数组

Merging perl array which contains hashes in it

我正在尝试在 perl 中进行合并,其中包含哈希的数组,我试图在合并时不合并数组中的重复元素(通过 uniq 函数)。

use strict;
use Hash::Merge qw/merge/;
use List::MoreUtils qw/uniq/;
use Data::Dumper;

my $h1 = { name1    => [ {
                           sport  => "tennis",
                           country => "us",
                          },
                          {
                           sport => "soccer",
                           country => "brazil",
                          },
                          {
                           sport  => "cricket",
                           country => "india"
                          },
                        ]
        };

my $h2 = { name1 => [   {
                           sport => "soccer",
                           country => "brazil",
                          },

                        {
                           sport  => "boxing",
                           country => "china"
                         }
                          ],

        };

输出:-

$VAR1 = {
      'name1' => [
                   {
                     'country' => 'us',
                     'sport' => 'tennis'
                   },
                   {
                     'country' => 'brazil',
                     'sport' => 'soccer'
                   },
                   {
                     'sport' => 'cricket',
                     'country' => 'india'
                   },
                   {
                     'country' => 'brazil',
                     'sport' => 'soccer'
                   },
                   {
                     'country' => 'china',
                     'sport' => 'boxing'
                   }
                 ]
    };

当我尝试使用自定义合并方法进行合并时,我无法消除重复元素 ({ sport => "soccer" country => "brazil" })。似乎是因为 hash 格式的元素。我们有没有使用自定义合并技术来实现它的简单方法。谢谢!

您可以尝试展平数组中的子哈希,以便能够对它们应用 uniq。然后在删除重复项后将子哈希展开回来。例如:

Hash::Merge::specify_behavior(
  {
    SCALAR => {
        SCALAR => sub { $_[1] },
        ARRAY  => sub { [ $_[0], @{$_[1]} ] },
        HASH   => sub { $_[1] },
    },
    ARRAY => {
        SCALAR => sub { $_[1] },
        ARRAY  => sub { my_array_merge( $_[0], $_[1] ) },
        HASH   => sub { $_[1] },
    },
    HASH => {
        SCALAR => sub { $_[1] },
        ARRAY  => sub { [ values %{$_[0]}, @{$_[1]} ] },
        HASH   => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
    },
  },
  'setting merge',
);


my $h_data = merge($h1, $h2);

print Dumper $h_data;


sub flatten_array_of_hash {
    my ( $ar ) = @_;

    my @flat;
    for my $hash (@$ar) {
        die "Not hash ref" if !(ref $hash eq "HASH");
        my @ar;
        for my $key (sort keys %$hash) {
            push @ar, join $;, $key, $hash->{$key};
        }
        push @flat, join $;, @ar;
    }
    return \@flat;
}

sub my_array_merge {
    my ($a1, $a2) = @_;

    my $f1 = flatten_array_of_hash( $a1 );
    my $f2 = flatten_array_of_hash( $a2 );
    my @flat = uniq @$f1, @$f2;
    my @result;
    for my $item (@flat) {
        my %hash = split $;, $item;
        push @result, \%hash;
    }
    return \@result;
}