2012-05-18 98 views
0

所以我有一个哈希表是这样的:Perl的哈希键+值变量

M => 1 
S => 50 

我想要做这样的事情:

$var = map { "$hash{$_}"."$_\n" } keys %hash; 
print $var; 

,让我结束了一个变量打印看起来像:

1M50S 

不幸的是,地图语句不工作:( 是的它必须是分配编辑到一个变量,因为它在一个if语句中并根据条件而变化。有没有一个很好的干净的方式来做到这一点?

+1

顺便说一句,map函数工作得很好。 :) – pilcrow

+0

我不确定你的意思,但我指的是我的问题中的地图声明。 –

+0

他意味着地图声明正常工作;这项任务是不符合你期望的。它返回2吗? – gpojd

回答

1

可以,例如,串联第一值+键,然后做一个连接:

%hash = (M => 1, S => 50); 
$var = join("", map {$hash{$_} . $_} keys %hash); 
print $var . "\n" ; 

补充:如果要通过值进行排序,asumming它们都是数字:

%hash = (M => 1, S => 50, Z => 6); 
$var = join("", map {$hash{$_} . $_} sort { $hash{$a} <=> $hash{$b} } keys %hash); 
print $var . "\n" ; 

1M6Z50S 
+0

这个效果很好!谢谢,有没有什么方法可以指定顺序? –

+1

@Dan:映射前对键进行排序 – Martin

+0

@Dan:取决于您是按键还是按值排序,以及您想要的是字母数字顺序还是数字。我添加了一个示例 – leonbloy

1

你必须知道keys %hash是无序的,这意味着它的顺序可能会或可能不是你想要的。

我建议在这里使用有序列表来指定键。

且有不洁的方式

%time=(M=>1,S=>50); 
$var=join"",map{"$time{$_}$_"}('M','S'); 
#=> $var='1M50S' 
+0

这是一种尝试并指定顺序的方法吗?顺便说一下,M和S与分秒无关。他们是另一个软件的标志,但是能够订购标志会很有用,因为还有更多,所有这些:'MIDNSHP = X' –

+0

不确定你的意思是'尝试',但是你可以指定像'map {block}(a_list_of_ordered keys)'的顺序' – Jokester

4

只需使用反向:

my %hash = (M => 1, S => 50); 
my $var = reverse %hash; 
## use the next line instead if you need sorting 
#my $var = join '', map { $_ . $hash{ $_ } } reverse sort keys %hash; 
## or this 
#my $var = reverse map { $_ => $hash{ $_ } } reverse sort keys %hash; 
print $var; ## outputs 1M50S 
+2

+1很好的使用'reverse'。 – TLP

0

如果MIDNSHP=X是所有你想要的顺序按键,然后写

my $var = join '', map "$hash{$_}$_", split //, 'MIDNSHP=X'; 

如果散列可能包含少于一组完整的密钥,则使用此代替

my $var = join '', map "$hash{$_}$_", grep $hash{$_}, split //, 'MIDNSHP=X'; 
+0

'grep $ hash {$ _}'将失败,出现空字符串或零值。你需要'grep defined $ hash {$ _}' – TLP