继续学习perl的几个grep示例 4. 在当前目录里列出文本文件
@files = grep { -f and -T } glob '* .*'; print "@files\n";
这个就很容易理解哦。glob返回一个列表,它的内容是当前目录里的任何文件,除了以'.'开头的。{}是个code块,它包含了匹配它后面的列表的条件。这只是grep的另一种用法,其实与 grep EXPR,LIST 这种用法差不多了。-f and -T 匹配列表里的元素,首先它必须是个普通文件,接着它必须是个文本文件。据说这样写效率高点哦,因为-T开销更大,所以在判断-T前,先判断-f了。
5. 选择数组元素并消除重复
@array = qw(To be or not to be that is the question); @found_words = grep { $_ =~ /b|o/i and ++$counts{$_} < 2; } @array; print "@found_words\n";
运行结果是:To be or not to question
{}里的意思就是,对@array里的每个元素,先匹配它是否包含b或o字符(不分大小写),然后每个元素出现的次数,必须小于2(也就是1次啦)。 grep返回一个列表,包含了@array里满足上述2个条件的元素。
6. 从二维数组里选择元素,并且x<y
# An array of references to anonymous arrays @data_points = ( [ 5, 12 ], [ 20, -3 ], [ 2, 2 ], [ 13, 20 ] ); @y_gt_x = grep { $_->;[0] < $_->;[1] } @data_points; foreach $xy (@y_gt_x) { print "$xy->;[0], $xy->;[1]\n" }
运行结果是: 5, 12 13, 20
这里,你应该理解匿名数组哦,[]是个匿名数组,它实际上是个数组的引用(类似于C里面的指针)。
@data_points的元素就是匿名数组。例如:
foreach (@data_points){ print $_->;[0];}
这样访问到匿名数组里的第1个元素,把0替换成1就是第2个元素了。
所以{ $_->;[0] < $_->;[1] }就很明白了哦,它表示每个匿名数组的第一个元素的值,小于第二个元素的值。 而grep { $_->;[0] < $_->;[1] } @data_points; 就会返回满足上述条件的匿名数组列表。
7. 简单模拟数据库查询 复杂的{}示例
# @database is array of references to anonymous hashes @database = ( { name =>; "Wild Ginger", city =>; "Seattle", cuisine =>; "Asian Thai Chinese Korean Japanese", expense =>; 4, music =>; "\0", meals =>; "lunch dinner", view =>; "\0", smoking =>; "\0", parking =>; "validated", rating =>; 4, payment =>; "MC VISA AMEX", }, # { ... }, etc. );
sub findRestaurants { my ($database, $query) = @_; return grep { $query->;{city} ? lc($query->;{city}) eq lc($_->;{city}) : 1 and $query->;{cuisine} ? $_->;{cuisine} =~ /$query->;{cuisine}/i : 1 and $query->;{min_expense} ? $_->;{expense} >;= $query->;{min_expense} : 1 and $query->;{max_expense} ? $_->;{expense} <= $query->;{max_expense} : 1 and $query->;{music} ? $_->;{music} : 1 and $query->;{music_type} ? $_->;{music} =~ /$query->;{music_type}/i : 1 and $query->;{meals} ? $_->;{meals} =~ /$query->;{meals}/i : 1 and $query->;{view} ? $_->;{view} : 1 and $query->;{smoking} ? $_->;{smoking} : 1 and $query->;{parking} ? $_->;{parking} : 1 and $query->;{min_rating} ? $_->;{rating} >;= $query->;{min_rating} : 1 and $query->;{max_rating} ? $_->;{rating} <= $query->;{max_rating} : 1 and $query->;{payment} ? $_->;{payment} =~ /$query->;{payment}/i : 1 } @$database; }
%query = ( city =>; 'Seattle', cuisine =>; 'Asian|Thai' ); @restaurants = findRestaurants(\@database, \%query); print "$restaurants[0]->;{name}\n";
运行结果是:Wild Ginger
上述code不难看懂,但使用这样的code,即消耗内存,又难于维护。 |