华小飞_Perl 发表于 2016-09-10 22:11

请教:map函数的使用出错!

本帖最后由 华小飞_Perl 于 2016-09-10 22:21 编辑

只是一个练习,出现错误,请教各位了,源代码如下:
#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;

my @gilligan = qw( red_shirt hat luckey_socks water_bottle );
my @skipper = qw( blue_shirt hat jacket preserver sunscreen );
my @professor = qw( sunscreen water_bottle slide_rule batteries radio );

my %all = (
      Gilligan=> \@gilligan,
      Skipper   => \@skipper,
      Professor => \@professor,
);

my %ch_all = map {
      my $person = $_;
      map { $person => { $_ => 1 } } @{ $all{$person} };
} sort keys %all;

print Data::Dumper->Dump( [ \%ch_all ], [ qw(*ch_all) ] );
原来想构建的哈希数据结构如下:
%ch_all = (
            'Gilligan' => {
                            'luckey_socks' => 1,
                            'water_bottle' => 1,
                            'hat' => 1,
                            'red_shirt' => 1
                        },
            'Professor' => {
                           'slide_rule' => 1,
                           'water_bottle' => 1,
                           'batteries' => 1,
                           'sunscreen' => 1,
                           'radio' => 1
                           },
            'Skipper' => {
                           'jacket' => 1,
                           'sunscreen' => 1,
                           'preserver' => 1,
                           'blue_shirt' => 1,
                           'hat' => 1
                         }
          );
但实际运行下来如下:
%ch_all = (
            'Gilligan' => {
                            'water_bottle' => 1
                        },
            'Professor' => {
                           'radio' => 1
                           },
            'Skipper' => {
                           'sunscreen' => 1
                         }
          );
请问各位在map函数使用上存在哪些错误,请指正,谢谢!
(啰嗦了点,勿喷~)

sunzhiguolu 发表于 2016-09-10 23:02

分开写就行了.
#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;

my @gilligan = qw( red_shirt hat luckey_socks water_bottle );
my @skipper = qw( blue_shirt hat jacket preserver sunscreen );
my @professor = qw( sunscreen water_bottle slide_rule batteries radio );

my %all = (
      Gilligan=> \@gilligan,
      Skipper   => \@skipper,
      Professor => \@professor,
);

my %ch_all = map {
      my $person = $_;
      my %items = map {$_, 1} @{ $all{$person} };
      $person, \%items;
} sort keys %all;

print Data::Dumper->Dump( [ \%ch_all ], [ qw(*ch_all) ] );

zhlong8 发表于 2016-09-10 23:06

内层那个 map 返回的是
'Gilligan' => {'luckey_socks' => 1, },
'Gilligan' => {'hat' => 1},
'Gilligan' => {'red_shirt'=>1},
'Gilligan' => {'water_bottle =>1},

键都一样,放在一个 hash 里自然就互相覆盖了

华小飞_Perl 发表于 2016-09-11 09:05

回复 2# sunzhiguolu
谢谢大神,问题已解决~

华小飞_Perl 发表于 2016-09-11 09:19

回复 3# zhlong8

好的,按照您的见解,确实与运行结果相符的。但是在要构建的哈希的外层中键 $person 是相同的,可是值的话 { $_ => 1 },其中 $_ 不是会改变的吗,不应该会覆盖掉的啊,请指教?

104359176 发表于 2016-09-11 10:13

在不同的上下文中,$_ 是不同的

本帖最后由 104359176 于 2016-09-11 10:18 编辑

$_ 在不同的上下文中是不同的。
你这样写,$_ 其实是一个上下文。



sunzhiguolu 发表于 2016-09-11 10:47

本帖最后由 sunzhiguolu 于 2016-09-11 10:50 编辑

#!/usr/bin/perl
use strict;
use warnings;

my $pos = 0;
my @aColors = (, );
my %hPeople = map {
my $who = $_;
map { $who => {$_ => 1} } @{$aColors[$pos++]};
} qw /Tom Jim/;

for my $who (keys %hPeople){
    my @aClrs = keys %{$hPeople{$who}};
    print "$who favorite (@aClrs) colors.\n";
}

hztj2005 发表于 2016-09-11 11:44

华小飞_Perl 发表于 2016-09-11 09:19
回复 3# zhlong8

好的,按照您的见解,确实与运行结果相符的。但是在要构建的哈希的外层中键 $person...

<p>插入观察,说明数据是产生了的。结果不符合理想,可能与内层map的返回值,如何被perl解析有关。也许你这样写,perl就解析了最后一个数据。而按2楼的写法, perl就解析正确。</p><p>my %items = map {$_, 1} @{ $all{$person} };
</p><p>$person, \%items;</p><p>
</p><p>#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;


my @gilligan = qw( red_shirt hat luckey_socks water_bottle );
my @skipper = qw( blue_shirt hat jacket preserver sunscreen skirt);
my @professor = qw( sunscreen water_bottle slide_rule batteries radio book);

my %all = (
      Gilligan=> \@gilligan,
      Skipper   => \@skipper,
      Professor => \@professor,
);
my @temp;
my %ch_all = map
{
    my $person = $_;
    print $person."\n";
      
   map {
             print "$_\n";
             push @temp ,"$person ; { $_ => 1 }" ; #插入观察,说明数据是产生了的。      
              $person => { $_ => 1 }
   } @{ $all{$person} };
              
           
} sort keys %all;

print ("@temp");#插入观察,说明数据是产生了的。

print Data::Dumper->Dump( [ \%ch_all ], [ qw(*ch_all) ] );</p>

华小飞_Perl 发表于 2016-09-11 12:43

回复 6# 104359176
外层的 $_ 已经赋值给 $person 了,之后的 $_ 应该不是在另一个列表上下文了吗?请大神求教~

华小飞_Perl 发表于 2016-09-11 12:43

回复 7# sunzhiguolu

多谢,按照您的方法,可以了~
页: [1] 2
查看完整版本: 请教:map函数的使用出错!