Perl使用'map'重写这些代码

时间:2014-01-06 23:17:06

标签: perl

我可以使用'map'或类似功能使代码更简单吗?

# $animal and @loads are pre-defined somewhere else.

my @bucket;

foreach my $item (@loads) {

    push @bucket, $item->{'carrot'} if $animal eq 'rabbit' && $item->{'carrot'};

    push @bucket, $item->{'meat'} if $animal eq 'lion' && $item->{'meat'};

}

2 个答案:

答案 0 :(得分:3)

你在找这样的东西吗?

%foods = ( 'lion' => 'meat', 'rabbit' => 'carrot');

# ...

foreach my $item (@loads) {
    push @bucket, $item->{$food{$animal}} if $item->{$food{$animal}};
}

答案 1 :(得分:0)

使用更多样本数据可以更容易地回答这个问题。因为它是我需要做出很多假设。

假设:

@loads = (
    { carrot => 47, meat => 32, zebras => 25 },
    { carrot => 7,  zebras => 81 },       
);

@buckets应如下所示:

@buckets = ( 47, 32, 7 ); 

@animals看起来像时:

@animals = qw/ rabbit lion /;

这是一种地图方法。要理解它,你需要考虑值列表作为操作数而不是标量操作数:

my @animals = qw/ rabbit lion /;
my %eaten_by = (
    lion   => 'meat',
    rabbit => 'carrot',
    mouse  => 'cheese',
);

# Use a "hash slice" to get a list of foods consumed by desired animals.
# hash slices let you access a list of hash values from a hash all at once.
my @foods_eaten = @eaten_by{ @animals };

# Hint: read map/grep chains back to front.
#       here, start with map @loads and then work back to the assignment
my @bucket =
    grep $_,                   # Include only non-zero food amounts
    map @{$_}{@foods_eaten},   # Hash slice from the load, extract amounts of eaten foods.
    map @loads;                # Process a list of loads defined in the loads array

在一个详细的嵌套循环中重写:

my @buckets;
for my $item ( @loads ) {
    for my $animal ( @animals ) {
        my $amount = $item{ $eaten_by{$animal} };
        next unless $amount;

        push @buckets, $amount;
    }
}

使用哪一个?这完全取决于您的受众 - 谁将维护代码?你是否正在与一个Perl黑客团队合作,其中包括4个perl5porter?使用第一个。您的团队是由一两个实习生组成的,他们将会花费1%的时间来处理任何类型的代码吗?使用第二个示例。可能,你的情况处于中间位置。请自行决定。

快乐的黑客攻击!