How to Iterate the contents of multidimentional array in parallel using Perl - arrays

I have an array containing number of array. I am trying to get the element from each array parallely. Can some body please help me.
#shuffle= (
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
[ "fred", "barney" ]
);
I tried this, but it iterating the inner arrays sequentially.
my #fh;
#create an array of open filehandles.
#fh = map { #$_ } #shuffle;
foreach (#fh){
my $line = $_;
print $line."\n";
}
And out put is like this :
george
jane
elroy
homer
marge
bart
fred
barney
But I need the output like this :
george
homer
fred
jane
marge
barney
elroy
bart

The thing you need to bear in mind is when perl does an 'array of arrays' it's actually an array of array references.
What you're doing with your map there is dereferencing each in turn, and by doing so 'flattening' your array - taking all the elements in the first array reference, then the second and so on.
But that's not what you're trying to accomplish - you're trying to take the first element from each, then second, then third etc.
But what that map statement does do is allow you to count the total number of elements in your array, which can be used thus:
my #shuffle= (
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
[ "fred", "barney" ]
);
while ( map { #$_ } #shuffle ) {
foreach my $sub_array ( #shuffle ) {
print shift #$sub_array // '',"\n";
}
}
that's probably not an ideal way to test if you're finished though - but it does allow you to have varying lengths of inner arrays

You should use the each_arrayref function from the List::MoreUtils module.
The code would look like this:
use strict;
use warnings 'all';
use List::MoreUtils qw/ each_arrayref /;
use Data::Dump;
my #shuffle = (
[ qw/ george jane elroy / ],
[ qw/ homer marge bart / ] ,
[ qw/ fred barney / ],
);
my $iter = each_arrayref #shuffle;
while ( my #set = $iter->() ) {
dd \#set;
}
output
["george", "homer", "fred"]
["jane", "marge", "barney"]
["elroy", "bart", undef]

Try this
my #shuffle= (
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
[ "fred", "barney" ]
);
for my $i(0..$#shuffle)
{
for my $j(0..$#shuffle)
{
print "$shuffle[$j][$i]\n";
}
}

Related

Get the value of 2nd index by mapping 1st index through Hash of Arrays in Perl

I have a Perl file code state.pl where I am trying to retrieve full name of State based on State code from Hash of Arrays. Following is the code:
my $all_state_details = {
IN => [
[
"AP",
"Andhra Pradesh"
],
[
"AN",
"Andaman and Nicobar Islands"
],
[
"AR",
"Arunachal Pradesh"
],
],
US => [
[
"AL",
"Alabama"
],
[
"AK",
"Alaska"
],
[
"AS",
"American Samoa"
],
],
};
my $state = 'AN';
my $country = 'IN';
my #states = $all_state_details->{$country};
my #state_name = grep { $_->[0] eq $state } #states;
print #state_name;
When I run the script, I get the blank output
I want the output as just:
Andaman and Nicobar Islands
The #{ ... } dereference operation is necessary to convert the array reference in $all_state_details->{$country} into an array suitable for use with grep.
print map { $_->[1] }
grep { $_->[0] eq $state } #{$all_state_details->{$country}};
The right way to do this kind of lookup is with a hash of hashes.
e.g.
%all_state_details = (
IN => {
"AP" => "Andhra Pradesh",
"AN" => "Andaman and Nicobar Islands",
},
);
Then you just do a direct lookup.
print $all_state_details{IN}{AN};
Read https://perldoc.perl.org/perldsc.html#HASHES-OF-HASHES
HTH

Using join to concatenate array values

I have array values that is getting returned from SQL object.
my #keys = $db_obj->SelectAllArrayRef($sql);
print Dumper #keys;
gives
$VAR1 = [ [ '8853' ], [ '15141' ] ];
I need to create string from this array: 8853, 15141.
my $inVal = join(',', map { $_->[0] }, #$keys);
my $inVal;
foreach my $result (#$keys){
$inVal .= $result->[0];
}
my $inVal = join(',', #$keys);
Value i get is ARRAY(0x5265498),ARRAY(0x52654e0). I think its reference to the array. Any idea what am I missing here?
Don't pass arrays to Dumper; it leads to confusing output. $VAR1 is not a dump of #keys, it's a dump of $keys[0]. Instead, you should have done
print(Dumper(\#keys));
This would have given
$VAR1 = [ [ [ '8853' ], [ '15141' ] ] ];
The code you want is
join ',', map { $_->[0] }, #{ $keys[0] };
That said, it appears that ->SelectAllArrayRef returns a reference to the result, and so it should be called as follows:
my $keys = $db_obj->SelectAllArrayRef($sql);
For this,
print(Dumper($keys));
outputs
$VAR1 = [ [ '8853' ], [ '15141' ] ];
And you may use either of the methods you used in your question.
join ',', map { $_->[0] }, #$keys;
The first version should work for you:
my $arr = [ [ '8853' ], [ '15141' ] ];
my $values = join(',', map { $_->[0] } #$arr);
print $values . "\n";
8853,15141

access / print nth element of sub array, for every array

I have a multidimensional array:
#multarray = ( [ "one", "two", "three" ],
[ 4, 5, 6, ],
[ "alpha", "beta", "gamma" ]
);
I can access #multarray[0]
[
[0] [
[0] "one"
[1] "two"
[2] "three"
]
]
or even #multarray[0][0]
"one"
But how to I access say the 1st sub element of every sub array? something akin to multarray[*][0] so produce:
"one"
4
"alpha"
Thanks!
You can use map and dereference each array:
use warnings;
use strict;
use Data::Dumper;
my #multarray = (
[ "one", "two", "three" ],
[ 4, 5, 6, ],
[ "alpha", "beta", "gamma" ]
);
my #subs = map { $_->[0] } #multarray;
print Dumper(\#subs);
__END__
$VAR1 = [
'one',
4,
'alpha'
];
See also: perldsc
Using a for() loop, you can loop over the outer array, and use any of the inner elements. In this example, I've set $elem_num to 0, which is the first element. For each loop over the outer array, we take each element (which is an array reference), then, using the $elem_num variable, we print out the contents of the inner array's first element:
my $elem_num = 0;
for my $elem (#multarray){
print "$elem->[$elem_num]\n";
}

Why is my sort function not working

I have a file which I have read into an array, with multiple columns and I want to sort numerically by the second column. I've looked up countless similar questions and tried to directly incorporate the answers given.
here is the basic code I am using:
use strict;
use warnings;
use diagnostics;
my #arrayed = (
"\ndog", "10", "barks",
"\ncat", "20", "meows",
"\nfish", "5", "plop",
"\nant", "30", "walk",
);
print "#arrayed";
print "\n";
my #sortedarray = sort { $a->[1] <=> $b->[1] } #arrayed;
print "#sortedarray";
exit;
This gives me an error cant use string ("dog") as an array reference while strict is turned on. I tried a few other examples with other files, arrays but always get this message so I assume there must be something intrinsically wrong with my code.
could anybody more experienced shed a little light on what I'm doing wrong please, and allow me to sort by the numbered column while still maintaining the row structure.
You have a flat array, but you want an array-of-arrays:
use strict;
use warnings;
use diagnostics;
use Data::Dumper;
my #arrayed = (
["dog", "10", "barks"],
["cat", "20", "meows"],
["fish", "5", "plop"],
["ant", "30", "walk"],
);
print Dumper(\#arrayed);
my #sortedarray = sort { $a->[1] <=> $b->[1] } #arrayed;
print Dumper(\#sortedarray);
__END__
$VAR1 = [
[
'dog',
'10',
'barks'
],
[
'cat',
'20',
'meows'
],
[
'fish',
'5',
'plop'
],
[
'ant',
'30',
'walk'
]
];
$VAR1 = [
[
'fish',
5,
'plop'
],
[
'dog',
10,
'barks'
],
[
'cat',
20,
'meows'
],
[
'ant',
30,
'walk'
]
];
Your assignment does not create a multi-dimensional array:
my #arrayed = (
"\ndog", "10", "barks",
"\ncat", "20", "meows",
"\nfish", "5", "plop",
"\nant", "30", "walk",
);
You would need to use array references inside those parentheses:
my #arrayed = (
[ "\ndog", "10", "barks" ],
[ "\ncat", "20", "meows" ],
[ "\nfish", "5", "plop" ],
[ "\nant", "30", "walk" ]
);
The brackets [ ... ] create anonymous array references, which can then be stored in the array.
One of the most important things to know when debugging is what your data looks like. Doing something like what you did
print "#arrayed";
Is not very useful, since it will only show a list of the elements separated by space. Also, if you had done this with a multi-dimensional array, you would get output like this:
ARRAY(0x7fd658) ARRAY(0x7fd7f0)
Which is what array references look like when stringified. Instead, you should use the Data::Dumper module:
use Data::Dumper;
print Dumper \#arrayed;
Notice that you are printing a reference to the array. The output would be a data structure looking like what toolic has shown in his answer:
$VAR1 = [
[ ...
Note that the brackets, again, denote array references.

initialise list with every element is a an associative array and last elment of the associative array is two d array in perl?

I'm trying to create a database .Each element in list contains details in the form of associative array and the last element of each of these associative array is a 2-d array,i need help initializing it ..
You need to say much more about what it is you are trying to do, but this may help: it initialises a Perl data structure in the way you have described. Note that there can be no "last" element of a hash (a better name than "associative array") as hashes are unordered. I have used the customers field of the data to hold the 2D array you talked about.
use strict;
use warnings;
my #list = (
{
id => 1,
name => 'cattle',
customers => [
[ 'World Bank', 'Space Marines', 'Undersea Exploration' ],
[ 1, 2, 3 ],
[ 0.0500, 0.6322, 0.9930 ],
],
},
{
id => 2,
name => 'arable',
customers => [
[ 'Jack Spratt', 'Molly Malone', 'The Whistler' ],
[ 4, 5, 6 ],
[ 0.0022, 0.1130, 0.6930 ],
],
},
{
id => 3,
name => 'seafood',
customers => [
[ 'Tai Chi School of Fishery', 'Latin Intermediary College', 'Ping Pong Gymnastics' ],
[ 7, 8, 9 ],
[ 0.0012, 0.8540, 0.9817 ],
],
},
);

Resources