免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 898 | 回复: 0
打印 上一主题 下一主题

Hash slices can replace loops [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-17 00:13 |只看该作者 |倒序浏览

Perl 5: Hash slices can replace loops
By Vince V. on May 26, 2008 12:00 PM |
No Comments

How many times have you written a for loop to do something simple with a hash and thought, there must be a better way to do this? Using hash slices instead of simple loops can save you lines of code and execution time.
A hash slice is a syntax for accessing the values of multiple keys of a hash in a single statement. It is a succinct and efficient technique, but it is also one of those collections of punctuation that give Perl a reputation as a write-only language. Once you have learned it, however, you will feel much more clever! Here are a few examples of how I use hash slices to make my code shorter and faster. (Note that you can also slice arrays, but today we are just talking about hashes.)
Basic hash slice syntax
You perform a hash slice by using a list as a hash index, rather than a scalar value, and preceding with the @ sigil rather than the $ sigil you would use to get a scalar value.
my %number_for = (one => 1, two => 2, three => 3);
# Regular access to scalar key
print $number_for{one}; # 1
# Hash slice accesses multiple keys. Note the '@'
print @number_for{qw(one two three)}; # 123
# This also works
print @number_for{'one','two','three'}; # 123
A cautionary note: notice how the scalar index uses a bare word as the key. Perl gives you the quoting for free in this case. With a slice, Perl doesn't help, so you have to do the quoting yourself.
Merging two hashes
Since hash slices can be lvalues, they can be used to merge one hash into another. A common example is when you get configuration information from more than one source, but you want to consolidate it to look up in just one place.
my %your_numbers = (two => 2, four => 4, six => 6);
# I get all your numbers!
# (And your number will override mine if they differ)
@number_for{keys %your_numbers} = values %your_numbers;
print sort values %number_for; # 12346
Accessing keys in a particular order
Here is a common thing you run into in web development. You have received input from a web form and validated it. (You have validated it, right?) The data lives in a hash, and you want to store it in a database. You have your SQL statement all prepared, but it requires that the values be bound in exact column order. Unfortunately, the values function cannot be relied upon to return the values in the order you want. (And besides, you don't want to store the value of the submit button!)
# get valid data from your validation code
my %validated = %number_for;
# Columns of your table, in order needed by your SQL
my @columns = qw(six one three);
# Get the bind values with a slice
my @bind = @validated{@columns}; # 6,1,3
Accessing values sorted by keys
Say you want to sort a hash by its keys, and then use the values in that sorted order. Using the above data, perhaps we want to print numbers in alphabetical order.
print @number_for{sort keys %number_for}; # 41632
Slicing a hash reference
Eventually you will find yourself with a reference to a hash, and you will discover that the above syntax does not work. You may try three or four different combinations of curlies and arrows that just generate errors. Don't give up! You can slice a hashref! First, let's review using a hashref to get at scalar values.
my $num_for = \%number_for;
# Common syntax for dereferencing and getting a scalar index
print $num_for->{one}; # 1
# Alternate syntax, the lazy way:
print $$num_for{two}; # 2
# Alternate syntax, the explicit way
print ${$num_for}{six}; # 6
The key to slicing a reference to a hash is to use the alternate syntax shown above, replacing the initial $ sigil with @.
# The lazy way:
print @$num_for{@columns}; # 613
# The explicit way:
print @{$num_for}{@columns}; # 613
Note the distinct absence of the "arrow" syntax. The arrow implies a scalar, and we want a list.
Powerful syntax
The hash slice is an advanced syntax demonstrating Perl's concision and expressiveness. Now you should be able to recognize it when you see it, and hopefully apply it to your own projects to save time and space. (But remember, use your Perl superpowers only for Good, never for Evil!)
For a semi-regular diet of great Perl programming tips,
subscribe to the Webquills.net feed
or
get Webquills.net via email
.


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/5591/showart_1419636.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP