2

次の内容の 2 つの perl ハッシュを取得しました。

初め:

$VAR1 = {
      'name1' => [
                   'adam',
                   'bob'
                 ],
      'name2' => [
                  'Miller',
                  'Schumacher'
                ]
    };

2番:

$VAR1 = {
      'name1' => [
                   'tina',
                   'jason',
                   'jeff'
                 ],
      'name2' => [
                  'Miller',
                  'Schumacher',
                  'Schmidt'
                ]
    };

両方をマージして、次の構造を取得し、 name2 で一意のアイテムを取得するにはどうすればよいですか?

$VAR1 = {
      'name1' => [
                   'tina',
                   'jason',
                   'jeff',
                   'adam',
                   'bob',
                 ],
      'name2' => [
                  'Miller',
                  'Schumacher',
                  'Schmidt'
                ]
    };
4

4 に答える 4

2

Hash::Mergeモジュールの正しい先行動作は、配列をマージするときに要素を統合するようにカスタマイズされています。

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

my $href1 = { name1 => [ qw/adam bob/ ],
              name2 => [ qw/Miller Schumacher/ ] };

my $href2 = { name1 => [ qw/tina jason jeff/ ],
              name2 => [ qw/Miller Schumacher Schmidt/ ] };

Hash::Merge::specify_behavior(  {
                        SCALAR => {
                                SCALAR => sub { $_[1] },
                                ARRAY  => sub { [ $_[0], @{$_[1]} ] },
                                HASH   => sub { $_[1] },
                        },
                        ARRAY => {
                                SCALAR => sub { $_[1] },
                                # This returns unique elements from two arrays passed
                                ARRAY  => sub { [ uniq( @{$_[0]}, @{$_[1]}) ] },
                                HASH   => sub { $_[1] }, 
                        },
                        HASH => {
                                SCALAR => sub { $_[1] },
                                ARRAY  => sub { [ values %{$_[0]}, @{$_[1]} ] },
                                HASH   => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) }, 
                        },
                }, 
                'Right precedent + Uniq array', 
        );

my $href3 = merge($href1, $href2);

print Dumper $href3;

出力を生成します。

$VAR1 = {
          'name2' => [
                       'Miller',
                       'Schumacher',
                       'Schmidt'
                     ],
          'name1' => [
                       'adam',
                       'bob',
                       'tina',
                       'jason',
                       'jeff'
                     ]
        };
于 2015-10-03T12:40:56.940 に答える
1

キーをループして、配列からname1, name2重複を除外する必要が あります。$VAR2->{$k}$VAR1->{$k}

use strict;
use warnings;

my $VAR1 = {
      'name1' => [ 'adam', 'bob' ],
      'name2' => [ 'Miller', 'Schumacher' ]
};
my $VAR2 = {
      'name1' => [ 'tina', 'jason', 'jeff' ],
      'name2' => [ 'Miller', 'Schumacher', 'Schmidt' ]
};

my %result;
for my $k (keys %$VAR1) {
  my %seen;
  $result{$k} = [
    grep { !$seen{$_}++ } @{ $VAR2->{$k} }, @{ $VAR1->{$k} }
  ];
}

use Data::Dumper;
print Dumper \%result;

出力

$VAR1 = {
      'name2' => [
                   'Miller',
                   'Schumacher',
                   'Schmidt'
                 ],
      'name1' => [
                   'tina',
                   'jason',
                   'jeff',
                   'adam',
                   'bob'
                 ]
    };
于 2015-10-03T10:01:29.873 に答える