0

I have an array of elements combined with # which I wish to put in hash , first element of that array as key and rest as value after splitting of that array elements by # But it is not happening.

Ex:

my @arr = qw(9093#AT#BP 8111#BR 7456#VD#AP 7786#WS#ER 9431#BP ) #thousand of data 

What I want is

$hash{9093} = [AT,AP];
$hash{8111} = [BR]; and so on

How we can accomplish it using map function. Otherwise I need to use for loop but I wish to use map function.

1
  • You should run your Perl code with use strict and use warnings in effect. For example: Possible attempt to put comments in qw() list. Commented Dec 16, 2013 at 14:44

5 Answers 5

6
my %hash = map { my ($k, @v) = split /#/; $k => \@v } @arr;

For comparison, the corresponding foreach loop follows:

my %hash;
for (@arr) {
   my ($k, @v) = split /#/;
   $hash{$k} = \@v;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you ikegami, Your answer is similar to tobyink. So, I would choose his answer as best. Thank you guys for such a fast response.
If you're going to format the code as his answer, then you'd be better off using a foreach loop!
But if you both have written the same code, only diff is variable name though I used your code. Thank you all
5

Use split to split on '#', taking the first chunk as the key, and keeping the rest in an array. Then create a hash using the keys and references to the arrays.

use Data::Dumper;

my @arr  = qw( 9093#AT#BP 8111#BR 7456#VD#AP 7786#WS#ER 9431#BP );
my %hash = map {
   my ($key, @vals) = split '#', $_;
   $key => \@vals;
} @arr;

print Dumper \%hash;

1 Comment

Thanks Tobyink. It didn't come in my mind that we can assign and write some codes like this. Very well done! It helped
2

No effort shown in your question, but I am on a code freeze so I'll bite :)

A think that a for loop would be more idiomatic Perl here, process the elements one-by-one, split on # and then assign into your hash:

use strict;
use warnings; 
use Data::Dumper;

my @arr = qw(9093#AT#BP 8111#BR 7456#VD#AP 7786#WS#ER 9431#BP );
my %h;

for my $elem ( @arr ) {
   my ($key, @vals) = split /#/, $elem; 

   $h{$key} = \@vals;
}
print Dumper \%h;

Comments

1

That is easy:

%s = (map {split(/#/, $_, 2)} @arr);

Testing it:

$ cat 1.pl
my @arr = qw(9093#AT#BP 8111#BR 7456#VD#AP 7786#WS#ER 9431#BP );
%s = (map {split(/#/, $_, 2)} @arr);
foreach my $key ( keys %s )
{
  print "key: $key, value: $s{$key}\n";
}

$ perl 1.pl
key: 7456, value: VD#AP
key: 8111, value: BR
key: 7786, value: WS#ER
key: 9431, value: BP
key: 9093, value: AT#BP

1 Comment

Not quite. Does 9093 => 'AT#BP' instead of 9093 => [ 'AT', 'BP' ]
1
use strict;
use warnings; 
use Data::Dumper;

my @arr = ('9093#AT#BP', '8111#BR', '7456#VD#AP', '7786#WS#ER', '9431#BP' );
my %h = map { map { splice(@$_, 0, 1), $_ } [ split /#/ ] } @arr;
print Dumper \%h;

Comments

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.