print array of arrays with a separator - perl

I have written a simple perl script:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Pair = '';
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Terse = 1;
my #A=( [ 1,2 ],[ 3,4,5 ], [ 6,7,8 ]);
print Dumper(#A);
The output i get is :
> ./temp9.pl
[
1,
2
]
[
3,
4,
5
]
[
6,
7,
8
]
But what i need is the elements(arrays) to be separated with a comma , in between them.
I am much familiar in using Data:Dumper. Is there any fix for this?
The expected output is :
[
1,
2
],
[
3,
4,
5
],
[
6,
7,
8
]
Anothere question i have is is there any way in data dumper where i can add some text before each element in an array?for example here in array of array , can i add "xyz" before the opening brace of each array?

UPDATED#2
Try with print 'my $aRef = ', Dumper(\#A), ";";. It will print like this:
my $aRef = [
[
1,
2
],
[
3,
4,
5
],
[
6,
7,
8P
]
]
;
If You want to change the output of Dumper you can redirect the stdout to a variable (see open).
print map { "Something $_\n" } split "\n", Dumper(\#A);
Output:
Something [
Something [
Something 1,
Something 2
Something ],
Something [
Something 3,
Something 4,
Something 5
Something ],
Something [
Something 6,
Something 7,
Something 8
Something ]
Something ]

Related

Fill Multidimensional Array with two variables in loop

I am new to PERL and I try to get the following result in a loop:
# ResultFistStep.
$VAR1 = [
[
'Hello1'
],
[
'Hello2'
],
[
'Hello3'
],
];
But if i use a reference for the InnerArray \#InnerArray:
# Example1
my #OuterArray;
my #InnerArray;
foreach(1,2,3)
{
#InnerArray[0] = "Hello" . $_;
push(#OuterArray, \#InnerArray);
}
print Dumper \#OuterArray;
... i get this result:
$VAR1 = [
[
'Hello3'
],
$VAR1->[0],
$VAR1->[0]
];
If i try it without the reference:
# Example2
my #OuterArray;
my #InnerArray;
foreach(1,2,3)
{
#InnerArray[0] = "Hello" . $_;
push(#OuterArray, #InnerArray);
}
print Dumper \#OuterArray;
.. i get this result:
$VAR1 = [
'Hello1',
'Hello2',
'Hello3'
];
But what i want is the result shown at the beginning (ResultFistStep) and at some point in the end the following result (ResultFinally):
# ResultFinally
$VAR1 = [
[
'Hello1',
[
[],
[]
]
],
[
'Hello2',
[
[],
[]
]
],
[
'Hello3',
[
[],
[]
]
],
];
So the questions are:
How do i get this result for the ResultFirstStep done?
Can i solve the problem from ResultFinally with Perl?
Can please someone help me? I dont see the mistake.
Just use anonymous arrays:
my #outer;
push #outer, [ "Hello$_", [ [], [] ] ] for 1 .. 3;
or even
my #outer = map [ "Hello$_", [ [], [] ] ], 1 .. 3;
If you want to use the inner array, declare it inside the loop, otherwise you're reusing the same array again and again:
my #outer;
for (1 .. 3) {
my #inner = ( "Hello$_", [ [], [] ] );
push #outer, \#inner;
}

perl: How to I count multiple values in hash into a new hash?

My current hash:
%hash = (
"foo",
[
"apple",
"orange",
"apple",
"apple"
],
"bob",
[
"apple",
"orange",
],
);
How do I obtain this output?
%hash2 = (
apple => 4,
orange => 2,
);
my %counts;
for (values(%hash)) { # Iterate over the values of the hash, the references to the arrays.
for (#$_) { # Iterate over the values of the referenced array.
++$counts{$_};
}
}
or
my %counts;
++$counts{$_} for map #$_, values %hash;

mongodb: same field value, but cannot find the specific document using find() function

Put my question more clear: I am using mongodb, each document in the collection looks like:
{
u'cell_latlng': {
u'type': u'Polygon',
u'coordinates': [
[
[
...
],
[
...
],
[
...
],
[
...
]
]
]
},
u'self': {
u'Bus Line': 1,
u'Meeting Room': 1,
u'Neighborhood': 1,
u'Home (private)': 1,
u'Food': 1,
u'High School': 2,
u'Elementary School': 1,
u'Beach': 1,
u'Other Repair Shop': 1
},
u'_id': ObjectId('5545bed4e139c7dcde660f5a'),
u'point_latlng': {
u'type': u'Point',
u'coordinates': [
...
]
},
u'area': 100
}
Now I need to find a specific doc in the collection (the collection is called citymap). I know the value of the field 'self' and the value is called feature[0], so I just use:
results = citymap.find({'self':feature[0]})
However,
results.count() == 0
I check the feature[0] again and I am sure it is:
feature[0] = {u'Bus Line': 1, u'Meeting Room': 1, u'Neighborhood': 1, u'Home (private)': 1, u'Food': 1, u'High School': 2, u'Elementary School': 1, u'Beach': 1, u'Other Repair Shop': 1}
which is exactly the same as that in the doc, so why cannot I find this doc using this sentence?
Great thanks to any help
Let's check this script. Suppose your feature object like this
var feature = {u'Bus Line': 1, u'Meeting Room': 1, u'Neighborhood': 1, u'Home (private)': 1, u'Food': 1, u'High School': 2, u'Elementary School': 1, u'Beach': 1, u'Other Repair Shop': 1}
Iterate over feature object and append every keys as self and push them into new object. Check below function:
var appendSelf = {};
function appendData(data) {
for (var k in data) {
if (data.hasOwnProperty(k)) {
appendSelf["self.".concat(k)] = data[k]; //append self to every keys and set it's respective values
}
}
}
Now call this function as appendData(feature) on console if you type appendSelf then it shows object with appending self like this
> appendSelf
{
"self.u'Bus Line": 1,
"self.u'Meeting Room": 1,
"self.u'Neighborhood": 1,
"self.u'Home (private)": 1,
"self.u'Food": 1,
"self.u'High School": 4,
"self.u'Elementary School": 1,
"self.u'Beach": 1,
"self.u'Other Repair Shop": 1
}
So use this appendSelf in find criteria as citymap.find(appendSelf[0]).pretty() it show expected result.

Working with lists in Perl

I have two lists a and b as follows:
a = ('church.n.01','church.n.02','church_service.n.01','church.n.04')
b = ('temple.n.01','temple.n.02','temple.n.03','synagogue.n.01')
I want to find relatedness between members of a and b using function get_relatedness(arg1,arg2). How can I operate on a and b in Perl so that I will pass all possible combinations between a and b using two nested for loops in Perl.
Please help me to solve this as I am new to Perl.
my #a = ('church.n.01','church.n.02','church_service.n.01','church.n.04');
my #b = ('temple.n.01','temple.n.02','temple.n.03','synagogue.n.01');
use Data::Dumper;
print Dumper [ get_relatedness(\#a, \#b) ];
sub get_relatedness {
my ($c, $d) = #_;
return map { my $t=$_; map [$t, $_], #$d } #$c;
}
output
$VAR1 = [
[
'church.n.01',
'temple.n.01'
],
[
'church.n.01',
'temple.n.02'
],
[
'church.n.01',
'temple.n.03'
],
[
'church.n.01',
'synagogue.n.01'
],
[
'church.n.02',
'temple.n.01'
],
[
'church.n.02',
'temple.n.02'
],
[
'church.n.02',
'temple.n.03'
],
[
'church.n.02',
'synagogue.n.01'
],
[
'church_service.n.01',
'temple.n.01'
],
[
'church_service.n.01',
'temple.n.02'
],
[
'church_service.n.01',
'temple.n.03'
],
[
'church_service.n.01',
'synagogue.n.01'
],
[
'church.n.04',
'temple.n.01'
],
[
'church.n.04',
'temple.n.02'
],
[
'church.n.04',
'temple.n.03'
],
[
'church.n.04',
'synagogue.n.01'
]
];
To compare all combinations of elements in the two arrays using two nested loops, you just need to loop through one and, for each element of the first array, do an inner loop over the elements of the second array:
my #a = ('church.n.01','church.n.02','church_service.n.01','church.n.04');
my #b = ('temple.n.01','temple.n.02','temple.n.03','synagogue.n.01');
my $relatedness;
for my $outer (#a) {
for my $inner (#b) {
$relatedness += get_relatedness($outer, $inner);
}
}

Slice an array in MongoDB's aggregation framework

I am saving game results in MongoDB and would like to calculate the sum of the 3 best results for every player.
With the aggregation framework I am able to built the following intermediate pipeline result from my database of finished games (each player below has finished 5 games with the gives score):
{
"_id" : "Player1",
"points" : [ 324, 300, 287, 287, 227]
},
{
"_id" : "Player2",
"points" : [ 324, 324, 300, 287, 123]
}
Now I need to sum up the three best values for each player. I was able to sort the array so it would also be ok here to get only the first 3 elements of each array to build the sum of the array in the next pipeline step.
$limit would work fine if I only need the result for one player. I also tried using $slice but that doesn't seem to work in the aggregation framework.
So how do I get the sum of the three best results for each player?
You mentioned that it would also be ok here to get only the first 3 elements of each array to build the sum of the array in the next pipeline step., so do it first, then use:
db.test.aggregate({'$unwind':'$points'},{'$group':{'_id':'$_id','result':{'$sum':'$points'}}}
to get the result.
$slice method for aggregation framework was added in 3.2 version of mongo. For a more detailed answer, take a look here.
And a couple of examples from the mongo page:
{ $slice: [ [ 1, 2, 3 ], 1, 1 ] } // [ 2 ]
{ $slice: [ [ 1, 2, 3 ], -2 ] } // [ 2, 3 ]
{ $slice: [ [ 1, 2, 3 ], 15, 2 ] } // [ ]
{ $slice: [ [ 1, 2, 3 ], -15, 2 ] } // [ 1, 2 ]