How can I print a Perl hash in specific order?

2019-04-13 16:26发布

问题:

I have this code

#!/usr/bin/perl
use strict;

my @a = ("b","a","d","c");
my %h = ("a",1,"b",2,"c",3,"d",4);

#print '"' . join('","', @a), "\"\n";

print "\n";
foreach my $key (@a) {
    print '"' . $h{$key} . '",';
}
print "\n";

that outputs

"2","1","4","3",

but I would like that it just outputted

"2","1","4","3"

Notice that last ',' isn't there.

Is it possible to e.g. print a hash in a specific order, or some other trick to get the output I want?

Update:

Based on friedo's answer I was able to get it right.

print '"' . join('","', @h{@a}), "\"\n";

Friedo's answer doesn't have the quotes around the values.

回答1:

You can use a hash slice to get the values, then use join to stick them together with commas.

print join ",", @h{@a};


回答2:

print join("," => map qq["$_"], @h{@a}), "\n";

At the heart of this line is @h{@a}, a hash slice that means the same as

($h{"b"}, $h{"a"}, $h{"d"}, $h{"c"})

The obvious advantage is economy of expression.

Moving out one level, we find the map operator: for each value from @h{@a}, wrap it in double quotes using qq["$_"]. Because you want double quotes in the result, the code uses qq// to switch delimiters. Otherwise, you'd be stuck with "\"$_\"" or a concatenation chain as in your question.

Finally, join inserts commas between the mapped values. In this case, => is identical to the comma operator, but I use it here instead of

join(",", ...)

which I find visually unpleasing because of the commas being crammed together.

You may be tempted to write the join without parentheses, but doing so would make "\n" an argument to join rather than print.



回答3:

Use join to put commas between values and not at the end, and map to wrap each value in double quotes.

print join(",", map { qq|"$h{$_}"| } @a);


标签: arrays perl hash