How to recreate perl's array of hashes in golang? - perl

In perl I can push $hashref into #array and have this data for next foreach and possible encode_json (HTTP POST).
I can't figure out how to recreate the same login in golang?
$VAR1 = [
{
'address' => 'test.com',
'id' => 101,
'hostgroups' => [
zero
'one',
'or many'
],
'host_name' => 'test.com',
'alias' => 'test.com',
'template' => 'generic',
'file_id' => 'etc/config'
},
{
'address' => 'test2.com',
'id' => 102,
'hostgroups' => [
zero
'one',
'or many'
],
'host_name' => 'test2.com',
'alias' => 'test2.com',
'template' => 'generic',
'file_id' => 'etc/config'
},
(..)

var array = []map[string]interface{}{
{"address": "test.com", "hostgroups": []string{"zero", "one", "or many"}, "id": 101},
{"address": "test2.com", "hostgroups": []string{"zero", "one", "or many"}, "id": 102},
}

This is the answer.
type host map[string]interface{}
var hosts []host
h := host{
"id": id,
"file_id": "etc/config/hosts.cfg",
"host_name": host_name,
"alias": host_name,
"address": host_name,
"hostgroups": hg,
"template": "generic-host",
}
hosts = append(hosts, h)

Related

perl asn1 module encode SEQUENCE OF SEQUENCE

In the exmaple below, the asn1 definition has two tags schoolId and student. The tag student is SEQUENCE of SEQUENCE. I get the student info from a a file in JSON format such as:
{"school1": [{"name": "jason","id": 12345, "age": 14}, {"name": "karen","id": 12346, "age": 14},{"name": "mike","id": 12347, "age": 15}]}
{"school2": [{"name": "dave","id": 12645, "age": 16}, {"name": "angel","id": 12346, "age": 14},{"name": "susan","id": 12347, "age": 15}]}
So each school has a different number of students. My question is how to encode the student tag since it has unspecified number of students.
Thanks for your help!
use Convert::ASN1;
use Data::Dumper;
my %scope = qw(base 0 one 1 single 1 sub 2 subtree 2);
my %deref = qw(never 0 search 1 find 2 always 3);
my $search_pdu = Convert::ASN1->new;
$search_pdu->prepare(q(
SEQUENCE {
schoolId INTEGER,
student [0] SEQUENCE OF SEQUENCE {
name STRING,
id INTEGER,
age INTEGER
}
}
)) or die $search_pdu->error;
$buf = $search_pdu->encode(
schoolId => 1001,
student => [
{
name => "Jason Howard",
id => 310089,
age => 14
},
{
name => " Angel Disante",
id => 310456,
age => 15
}
]
);
$Data::Dumper::Indent = 1;
print Dumper( $search_pdu->decode($buf));
$h = unpack("H*",$buf);
print $h,"\n";
My question, For example, if school1 has 100 students, school2 has 300 students, ......., is there any way to use a for loop in the encode function to figure out the number of students programmatically?
$student_json = "{"school-1001": [{"name": "jason","id": 12345, "age": 14}, {"name": "karen","id": 12346, "age": 14},{"name": "mike","id": 12347, "age": 15}]}";
student => [
for my $hashref (#{$student_json}) {
{
name => $hashref->{'name'},
id => $hashref->{'id'},
age => $hashref->{'age'}
}
]
I tried many ways to use the for loop as shown above to encode programmatically, but it always failed.
My question, For example, if school1 has 100 students, school2 has 300 students, ......., is there any way to use a for loop in the encode function to figure out the number of students programmatically?
$student_json = "{"student": [{"name": "jason","id": 12345, "age": 14}, {"name": "karen","id": 12346, "age": 14},{"name": "mike","id": 12347, "age": 15}]}";
student => [
for my $hashref (#{$student_json}) {
{
name => $hashref->{'name'},
id => $hashref->{'id'},
age => $hashref->{'age'}
}
]
Given a JSON string with the school and student data, you can try:
use feature qw(say);
use strict;
use warnings;
use Convert::ASN1;
use Data::Dumper;
use JSON::XS;
my $json = <<'END';
{
"school1": [{"name": "jason","id": 12345, "age": 14}, {"name": "karen","id": 12346, "age": 14},{"name": "mike","id": 12347, "age": 15}],
"school2": [{"name": "dave","id": 12645, "age": 16}, {"name": "angel","id": 12346, "age": 14},{"name": "susan","id": 12347, "age": 15}]
}
END
my $hash = decode_json $json;
my $search_pdu = Convert::ASN1->new;
$search_pdu->prepare(q(
school SEQUENCE OF SEQUENCE {
schoolId INTEGER,
student SEQUENCE OF SEQUENCE {
name STRING,
id INTEGER,
age INTEGER
}
}
)) or die $search_pdu->error;
my #schools;
my $data = {school => \#schools};
my $school_id = 1001;
for my $school ( keys %$hash ) {
my #students;
my $item = { schoolId => $school_id, student => \#students };
for my $student (#{$hash->{$school}}) {
push #students, $student;
}
push #schools, $item;
$school_id++;
}
my $buf = $search_pdu->encode( $data );
$Data::Dumper::Indent = 1;
print Dumper( $search_pdu->decode($buf));
Output:
$VAR1 = {
'school' => [
{
'student' => [
{
'name' => 'jason',
'id' => 12345,
'age' => 14
},
{
'name' => 'karen',
'id' => 12346,
'age' => 14
},
{
'age' => 15,
'id' => 12347,
'name' => 'mike'
}
],
'schoolId' => 1001
},
{
'schoolId' => 1002,
'student' => [
{
'age' => 16,
'id' => 12645,
'name' => 'dave'
},
{
'name' => 'angel',
'age' => 14,
'id' => 12346
},
{
'name' => 'susan',
'age' => 15,
'id' => 12347
}
]
}
]
};

Find average time between multiple datetime objects mongodb

I want to find the average time a client visit at particular location. My data structure is as follows:
{
"_id": ObjectId("5aea9f9a83b391f80e00a1b1"),
"Client": "ABC",
"Timestamp": "2018-05-03 10:47:42"
},
{
"_id": ObjectId("5aea9f9a83b391f80e00c1a1"),
"Client": "ABC",
"Timestamp": "2018-05-03 11:05:04"
} ,
{
"_id": ObjectId("5aea9f9a83b391f80e00a1e1"),
"Client": "ABC",
"Timestamp": "2018-05-03 13:05:04"
} ,
{
"_id": ObjectId("5aea9f9a83b391f80eaea1e1"),
"Client": "DEF",
"Timestamp": "2018-05-03 11:20:44"
}
I have just tried code so far in codeigniter
$optn = array(
array('$group' => array( '_id' => '$Client', 'date1' => array('$min' => '$Timestamp'), 'date2' => array('$max' => '$Timestamp'), 'avg_time' => array('$avg' => array('$subtract' => array('$date2', '$date1')))))
);
$repeatdata = $this->mongo_db->aggregate("logsdata", $optn);
echo '<pre>'; print_r($repeatdata);
It gives me result as:
Array
(
[waitedMS] => 0
[result] => Array
(
[0] => Array
(
[_id] => ABC
[date1] => 2018-05-03 10:47:42
[date2] => 2018-05-03 13:05:04
[avg_time] =>
)
[1] => Array
(
[_id] => DEF
[date1] => 2018-05-03 11:20:44
[date2] => 2018-05-03 11:20:44
[avg_time] =>
)
)
)

Looking of a value in blessed hash

I am a begginer in Perl an i am trying to get à value from à blessed hash.
The value is ip adresses, i tried that with no success
print $vm->guest->ipStack->dnsConfig->ipAddress;
print $vm->guest->ipStack{dnsConfig}{ipAddress};
$VAR1 = [
bless( {
"ipRouteConfig" => bless( {
"ipRoute" => [
bless( {
"gateway" => bless( {
"device" => 0,
"ipAddress" => "10.*******"
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "0.0.0.0",
"prefixLength" => 0
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"network" => "1***********",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"prefixLength" => 23
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 32,
"network" => "10**************",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 32,
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "1***********5"
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 4,
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "224.0.0.0"
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "255.255.255.255",
"prefixLength" => 32
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 64,
"network" => "fe80::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 128,
"network" => "fe80::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 8,
"network" => "ff00::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' )
]
}, 'NetIpRouteConfigInfo' ),
"dnsConfig" => bless( {
"dhcp" => 0,
"searchDomain" => [
"france"
],
"hostName" => "HOST",
"ipAddress" => [
"10.60****",
"10.6*****",
"10.8*****"
],
"domainName" => "france"
}, 'NetDnsConfigInfo' )
}, 'GuestStackInfo' )
]
Whatever you have dumped is an array, not a hash. You need to show the call to Dumper for us to help you properly
Also, since this is a structure of blessed objects, you should be using their methods to access information, not going by the "back door" and messing with the data structure directly. Unfortunately GuestStackInfo and NetDnsConfigInfo are VMware classes and not one of the standard Perl types so I can't suggest what method calls may be appropriate
Here are some notes
The structure referred to by $VAR1 is a one-element array containing a GuestStackInfo object
The GuestStackInfo object contains a NetIpRouteConfigInfo object and a NetDnsConfigInfo object. I assume you are interested in the latter as you say "The value is ip adresses", and the nearest hash key is ipAddress in the NetDnsConfigInfo object
The ipAddress element is reference to an array of IP address-like strings
To access this array you would write
my $addresses = $VAR1->[0]{dnsConfig}{ipAddress};
and then to print them all out, use
print "$_\n" for #$addresses;
But please take note of my initial comments -- you should be using method calls and not poking around the data structure like this. Is there any documentation for those classes?

Convert a flat datastructure into a tree

I have an array of hashes. Each element in the array is a node in a hierarchical tree and has referential data for who the parent is. I will have thousands and hundreds of thousands of nodes in the tree... essentially an unknown set of nodes has to be converted to JSON (shown below) for use with http://bl.ocks.org/robschmuecker/7880033
UPDATE: position_id is a node in the heretical tree. placement_id is the parent's position_id (adjacency referential tree).
UPDATE: Here's the full AoH Data::Dumper result with Nested Set and Adjacency result from a modified version of DBIx::Tree::NestedSet (custom).
$VAR1 = [
{
'lft' => '673',
'id' => '109',
'date_created' => '2015-08-15',
'level' => '7',
'user_id' => '13',
'placement_id' => '11',
'position_id' => '13',
'status' => '1',
'structure_id' => '1',
'rght' => '684'
},
{
'placement_id' => '13',
'position_id' => '22',
'status' => '1',
'structure_id' => '1',
'rght' => '679',
'lft' => '674',
'date_created' => '2015-08-15',
'id' => '116',
'level' => '8',
'user_id' => '22'
},
{
'user_id' => '101',
'level' => '9',
'id' => '200',
'date_created' => '2015-08-15',
'lft' => '675',
'rght' => '676',
'structure_id' => '1',
'status' => '1',
'position_id' => '101',
'placement_id' => '22'
},
{
'date_created' => '2015-08-15',
'id' => '201',
'level' => '9',
'user_id' => '374',
'lft' => '677',
'structure_id' => '1',
'rght' => '678',
'placement_id' => '22',
'position_id' => '374',
'status' => '1'
},
{
'lft' => '680',
'user_id' => '95',
'level' => '8',
'id' => '117',
'date_created' => '2015-08-15',
'status' => '1',
'position_id' => '95',
'placement_id' => '13',
'rght' => '681',
'structure_id' => '1'
}
];
THIS IS THE GOAL, For this example I need to end up with:
{
"name": "13",
"children": [
{
"name": "22",
"children": [
{
"name": "101"
},
{
"name": "374"
}
]
},
{
"name": "95"
}
]
}
You can also see the format I am trying to arrive at here (minus size):
http://bl.ocks.org/robschmuecker/7880033#flare.json
My failed approach(es) included various attempts at looping through the array of hashes to create a recursive Hash of Hashes that can then be used with the JSON Perl module to create the actual JSON I need.
my $data = [
{ position_id => 123, placement_id => undef },
{ position_id => 456, placement_id => 123 },
{ position_id => 789, placement_id => 123 },
# ...
];
my $roots;
{
my %recs_by_name;
my %children_by_parent_name;
for my $row (#$data) {
my $name = $row->{position_id};
my $parent_name = $row->{placement_id};
my $rec = {
name => $name,
};
push #{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
$recs_by_name{$name} = $rec;
}
$roots = delete($children_by_parent_name{root}) || [];
for my $name (keys(%children_by_parent_name)) {
my $children = $children_by_parent_name{$name};
if ( my $rec = $recs_by_name{$name} ) {
$rec->{children} = $children;
} else {
die("Parent $name doesn't exist.\n");
push #$roots, #$children;
}
}
}
print(Dumper($roots));
Tested.
You appear to have the depth of each node available to you (level). Simpler code could be used if your data was sorted by increasing depths.
While it was #ikegami who ultimately answered the question that led to the solution. I believe the following adaptation adds 4 important elements/clarifications I found helpful, and thought others reading this question and answer would also find useful.
1- Clear addition of all key,value pairs from the originating AoH to the resulting HOH. See while loop.
2- A Child node counter.
3- Inclusion and use of the encode_json function from JSON
4- The result is also an Array with a Hash as the first element. Newbies (like me) might find the explicit #{$roots}[0] passed to encode_json as helpful.
At first I had a similar adapted solution posted as an UPDATE within my question, but was admonished that it was bad etiquette and instructed to post an answer.
#ikegami's deserves the credit for the core of the solution.
sub get_jsonTree {
my ($array_of_hashes_ref) = #_;
my $roots;
my %recs_by_name;
my %children_by_parent_name;
my %count;
for my $row (#$array_of_hashes_ref) {
my $name = $row->{position_id};
my $parent_name = $row->{placement_id};
my $rec = {
name => $name,
};
## Added to loop through all key,value pairs and add them to $rec
while ( my ($key, $value) = each(%$row) ) {
$rec->{$key} = $value;
}
##Added To Count Child Nodes
$count{$parent_name} = 0 if (!$count{$parent_name});
$rec->{'child_count'} = $count{$parent_name};
$count{$parent_name}++;
push #{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
$recs_by_name{$name} = $rec;
}
$roots = delete($children_by_parent_name{root}) || [];
for my $name (keys(%children_by_parent_name)) {
my $children = $children_by_parent_name{$name};
if ( my $rec = $recs_by_name{$name} ) {
$rec->{children} = $children;
} else {
$util{'test'} .= "Parent $name doesn't exist.\n<BR>";
push #$roots, #$children;
}
}
use JSON;
my $json_str = encode_json(#{$roots}[0]);
return $json_str;
}
my $array_of_hashes_ref = [
{ position_id => 123, placement_id => undef },
{ position_id => 456, placement_id => 123 },
{ position_id => 789, placement_id => 123 },
# ...
];
my $json_str = &get_jsonTree($array_of_hashes_ref);

Append an element to an already existing SOAP::Data complex type

I'm very new to SOAP, PERL and pretty much everything else I've been asked to do so I'm hoping someone can point me in the right direction.
I've implemented a simple WCF solution and I've written a PERL client which passes a "complex data structure" to the solution using SOAP::lite and SOAP::Data. All this works very well so far, WCF solution see's the array as an array and I'm able to iterate through the array on the server side just fine.
However, I'm having an issue trying to append a data element to the array on the PERL side. I have the following code, which builds the array I need, but I need to append a few lines to the array later on in the code and I can't figure out how to that.
# build array of values
my $data= SOAP::Data->new
(name => 'array', value =>
[
SOAP::Data->new(name => 'elem:string', value => 'firststring'),
SOAP::Data->new(name => 'elem:string', value => 'secondstring'),
SOAP::Data->new(name => 'elem:string', value => 'thridstring')
]
)
->attr
(
{ 'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays','xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'}
);
# create a new element
my $elem1 = SOAP::Data->new(name => 'elem:string', value => 'addedstring');
# try to add the element
push(#{$data->{array}},$elem1);
#.... send, catch, print.. bla bla bla
The code I have runs, and the WCF service see's the array just fine, but the $elem1 value is never actually appended to the SOAP envelope.
Any help is GREATLY appreciated...
Take a look at what $data is using Data::Dumper, you get this
$VAR1 = bless( {
'_attr' => {
'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance',
'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
},
'_signature' => [],
'_name' => 'array',
'_value' => [
[
bless( {
'_value' => [
'firststring'
],
'_name' => 'string',
'_prefix' => 'elem',
'_signature' => [],
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_value' => [
'secondstring'
],
'_name' => 'string',
'_signature' => [],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_attr' => {},
'_value' => [
'thridstring'
],
'_name' => 'string',
'_signature' => [],
'_prefix' => 'elem'
}, 'SOAP::Data' )
]
]
}, 'SOAP::Data' );
There is no $data->{array}
A look at the documentation for SOAP::Data, says you should use $data->value to access the array you created.
push #{ $data->value }, $elem1;
print Dumper $data->value;
yields
$VAR1 = [
bless( {
'_attr' => {},
'_prefix' => 'elem',
'_value' => [
'firststring'
],
'_name' => 'string',
'_signature' => []
}, 'SOAP::Data' ),
bless( {
'_signature' => [],
'_name' => 'string',
'_value' => [
'secondstring'
],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_name' => 'string',
'_signature' => [],
'_value' => [
'thridstring'
],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_attr' => {},
'_prefix' => 'elem',
'_value' => [
'addedstring'
],
'_name' => 'string',
'_signature' => []
}, 'SOAP::Data' )
];
Thanks Gabs00,
push $data->value, $elem1; worked beautifully