Perl实用的集合操作

最近又需要给以前的程序添加个功能, 简单抽象一下就是取散列的前N大valuekey

问题很简单, 正好可以回顾一下perl的集合操作

这里先上一下代码:

get keys based on hash’s value
1
2
3
4
5
6
7
8
9
10
11
sub get_hash_top_n(\%$)
{
    my ($h, $n) = @_;

    return ((sort {
        $h->{$b} <=> $h->{$a}
    } keys %$h)[0 .. ($n-1)])
}

# call function
@top_n_keys = get_hash_top_n(%my_hash, $top_n);

数组排序

对于排序大家都很熟悉, 而perl中的排序也是十分的方便, 基本就是利用sort这个方法.

这里值得注意的是排序的稳定性. perl中的排序算法在不同版本中是不一样的, 具体详情请猛击这里. 因此当排序的稳定性很重要的, 需要手动指定:

the sort pragma
1
use sort 'stable';      # guarantee stability

数组切片

perl的数组和散列的切片是我认为最好用的操作之一, 可以大大简化代码量

获取数组n到m的元素

slice
1
@array[$n..$m]

这种类似的写法在ruby中也是ok的, 只需要把魔符去掉就是ruby版本的了.

针对不同的元素做不同的操作

在进一步, 假如说我们不单单只是想获取某些元素, 而且想针对特定的元素做特定的操作, 这个时候该怎么办呢? 很多时候我们就把切下来的元素保存到数组中, 而后依次做操作. 直到有一天膝盖中了一箭, 哦, 是在CU上看到一篇帖子, 然后学到了使用匿名函数来进行操作:

common
1
2
3
4
5
6
($year, $month, $day) = (localtime)[5,4,3];

$year += 1900;
$month += 1;

print "$year $month $day";

比较trick的做法:

another way
1
2
3
($year, $month, $day) = sub{($_[0]+1900,$_[1]+1,$_[2])}->((localtime)[5,4,3]);

print "$year $month $day";

是不是很cool很方便?当然还是不推荐这样写的,知道一下就可以了哈~

其他

最上面的代码用到了prototype. 有关prototype的争议还是不少的, 有很多人都不推荐使用它, 有兴趣的同学可以看看PerlMonks的讨论;)

这里指出一点, 使用prototype指定hash引用的时候小谨慎使用+, 在比较旧的版本中需要使用的是\%. 因此需要保持兼容性的话还是推荐使用老版本的写法.

写到这里感觉有点文不对题…表示自己思维很混乱…

Comments