0

So I have a hash table like this:

M => 1
S => 50

I want to do something like this:

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

so that I end up with a variable to print that looks like:

1M50S

Unfortunately the map statement doesn't work :( And yes it must be assigned to a variable because it is in an if statement and changes depending on conditions. Is there a nice clean way of doing this?

3
  • 1
    The map function works just fine, by the way. :) Commented May 18, 2012 at 19:42
  • I am not sure what you mean, but I was referring to the map statement in my question. Commented May 18, 2012 at 20:27
  • He means that the map statement works fine; the assignment is what's not doing what you expect. Does it return 2? Commented May 18, 2012 at 21:23

4 Answers 4

4

Just use reverse:

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
Sign up to request clarification or add additional context in comments.

Comments

1

you have to know that keys %hash is unordered, which means its order may or may not be what you want.

I recommend using a ordered list here to specify keys.

and there is an unclean way

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

2 Comments

Is this a way to try and specify the order? By the way the M and S have no correlation to minutes and seconds. They are flags for another software, but it would be useful to be able to order the flags, since there are many more, all of these: MIDNSHP=X
Not sure what you meant by 'try', but yes you can specify the order like map{block}(a_list_of_ordered keys)
1

You can, for example, concatenate first the value + key and then do a join:

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

Added: If you want to sort by values, asumming they are numeric:

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

1M6Z50S

2 Comments

@Dan: sort the keys before mapping
@Dan: it depends on whether you want to sort by keys or values, and whether you want alfanumeric order or numeric. I added an example
0

If MIDNSHP=X is all of the keys in the order you want them, then write

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

If the hash may contain less than a complete set of keys, then use this instead

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

1 Comment

grep $hash{$_} will fail for empty string or zero values. You will need grep defined $hash{$_}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.