当前位置:  开发笔记 > 编程语言 > 正文

Perl的地图有什么意义?

如何解决《Perl的地图有什么意义?》经验,为你挑选了9个好方法。

没有真正得到地图功能的重点.任何人都可以用例子解释它的用途吗

使用它而不是循环是否有任何性能优势,还是只是糖?



1> Adam Bellair..:

任何时候您想要基于另一个列表生成列表:

# Double all elements of a list
my @double = map { $_ * 2 } (1,2,3,4,5);
# @double = (2,4,6,8,10);

由于列表很容易成对转换为哈希值,因此如果您需要基于特定属性的对象哈希表:

# @user_objects is a list of objects having a unique_id() method
my %users = map { $_->unique_id() => $_ } @user_objects;
# %users = ( $id => $obj, $id => $obj, ...);

它是一个非常通用的工具,您必须开始使用它来在您的应用程序中找到好的用途.

为了便于阅读,有些人可能更喜欢详细的循环代码,但就个人而言,我发现它map更具可读性.



2> Sam Kington..:

首先,它是一种转换数组的简单方法:而不是说例如

my @raw_values = (...);
my @derived_values;
for my $value (@raw_values) {
    push (@derived_values, _derived_value($value));
}

你可以说

my @raw_values = (...);
my @derived_values = map { _derived_value($_) } @raw_values;

它对于构建快速查找表也很有用:而不是例如

my $sentence = "...";
my @stopwords = (...);
my @foundstopwords;
for my $word (split(/\s+/, $sentence)) {
    for my $stopword (@stopwords) {
       if ($word eq $stopword) {
           push (@foundstopwords, $word);
       }
    }
}

你可以说

my $sentence = "...";
my @stopwords = (...);
my %is_stopword = map { $_ => 1 } @stopwords;
my @foundstopwords = grep { $is_stopword{$_} } split(/\s+/, $sentence);

如果你想从另一个列表中导出一个列表,它也很有用,但不要特别需要让一个临时变量混乱,例如而不是

my %params = ( username => '...', password => '...', action => $action );
my @parampairs;
for my $param (keys %params) {
    push (@parampairs, $param . '=' . CGI::escape($params{$param}));
}
my $url = $ENV{SCRIPT_NAME} . '?' . join('&', @parampairs);

你说的更简单

my %params = ( username => '...', password => '...', action => $action );
my $url = $ENV{SCRIPT_NAME} . '?'
    . join('&', map { $_ . '=' . CGI::escape($params{$_}) } keys %params);

(编辑:修复了最后一行中缺少的"键%params")



3> Michael Carm..:

map函数用于转换列表.它基本上是用于替换某些类型的for[each]循环的语法糖.一旦你绕过它,你就会看到它的用处:

my @uppercase = map { uc } @lowercase;
my @hex       = map { sprintf "0x%x", $_ } @decimal;
my %hash      = map { $_ => 1 } @array;
sub join_csv { join(',', map {'"' . $_ . '"' } @_ }



4> toolkit..:

另请参阅Schwartzian变换以获得地图的高级用法.



5> cjm..:

它对于查找哈希也很方便:

my %is_boolean = map { $_ => 1 } qw(true false);

相当于

my %is_boolean = ( true => 1, false => 1 );

那里没有多少积蓄,但假设你想定义%is_US_state



6> kixx..:

map用于通过转换另一个列表的元素来创建列表.

grep用于通过过滤另一个列表的元素来创建列表.

sort用于通过对另一个列表的元素进行排序来创建列表.

这些运算符中的每一个都接收代码块(或表达式),用于转换,过滤或比较列表的元素.

对于map,块的结果将成为新列表中的一个(或多个)元素.当前元素别名为$ _.

对于grep,块的布尔结果决定是否将原始列表的元素复制到新列表中.当前元素别名为$ _.

对于sort,块接收两个元素(别名为$ a和$ b),并且预期返回-1,0或1中的一个,指示$ a是大于,等于还是小于$ b.

所述的Schwartzian变换使用这些运营商能够有效的缓存值(属性),以在一个分拣列表中使用,尤其是当计算这些性能具有一个非平凡成本.

它的工作原理是创建一个中间数组,该数组具有作为元素数组引用的原始元素和我们想要排序的计算值.这个数组被传递给sort,它比较已经计算好的值,创建另一个中间数组(这个被排序),然后传递给另一个抛出缓存值的map,从而将数组恢复到它的初始列表元素(但是现在按照所需的顺序).

示例(创建当前目录中按上次修改时间排序的文件列表):

@file_list = glob('*');
@file_modify_times = map { [ $_, (stat($_))[8] ] } @file_list;
@files_sorted_by_mtime = sort { $a->[1] <=> $b->[1] } @file_modify_times;
@sorted_files = map { $_->[0] } @files_sorted_by_mtime;

通过将运算符链接在一起,中间数组不需要声明变量;

@sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, (stat($_))[8] ] } glob('*');

您还可以在排序之前通过插入grep来过滤列表(如果要对相同的缓存值进行过滤):

示例(过去24小时内修改的文件列表,对最后修改时间进行了排序):

    @sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } grep { $_->[1] > (time - 24 * 3600 } map { [ $_, (stat($_))[8] ] } glob('*');



7> Craig H..:

map函数在列表的每个元素上运行一个表达式,并返回列表结果.可以说我有以下列表

@names = ("andrew", "bob", "carol" );

我想把这些名字的第一个字母大写.我可以遍历它们并调用每个元素的ucfirst,或者我可以执行以下操作

@names = map (ucfirst, @names);



8> Dima..:

map函数是函数式编程范例的一个概念.在函数式编程中,函数是第一类对象,这意味着它们可以作为参数传递给其他函数.地图是一个简单但非常有用的例子.它将一个函数(让我们称之为f)和一个列表作为其参数l. f必须是一个带有一个参数的函数,map只适用f于列表的每个元素l. f可以对每个元素执行任何操作:向每个元素添加一个元素,为每个元素添加方块,将每个元素写入数据库,或者为每个元素打开Web浏览器窗口,这恰好是一个有效的URL.

使用的优点map是它很好地封装了迭代列表的元素.你所要做的就是说" f对每一个元素都做,并且map决定如何最好地做到这一点.例如map可以实现在多个线程之间分割它的工作,并且它对调用者来说是完全透明的.

注意,这map完全不是Perl特有的.它是功能语言使用的标准技术.它甚至可以使用函数指针在C中实现,或者在使用"函数对象"的C++中实现.



9> Darron..:

"只是糖"是苛刻的.记住,循环只是糖 - 如果和goto可以做所有循环结构做的事情.

Map是一个足够高级别的功能,它可以帮助您在头脑中执行更复杂的操作,因此您可以编写和调试更大的问题.

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有