Perl dereferencing individual elements in array of hash of hash - mysql

I have a structure as below which contains array of hash of hash of hash. I am getting error while dereferencing the values from the hash.
$VAR1 = \{
'2001' => {
'Arunachal Pradesh' => {
'CHANGLANG' => [
{
'wheat' => '2',
'cotton' => '',
'rice' => '1'
}
],
'SUBANSIRI UPPER' => [
{
'wheat' => '',
'cotton' => '1',
'rice' => '2'
}
],
},
'Andhra Pradesh' => {
'CHITTOOR' => [
{
'wheat' => '34',
'cotton' => '14',
'rice' => '27'
}
],
'VIZIANAGARAM' => [
{
'wheat' => '2',
'cotton' => '',
'rice' => '8'
}
],
}
}
};
I am trying to dereferencing individual values such that I can fill these values to a mysql database. But I getting error "Use of uninitialized value $state in concatenation (.) or string" while derefrencing individual value itself. The code is as follows:
while (my ($key, $href) = each(%$stat) ) {
my $state = $stat->{$state_name}; #where the first value is the state name & the second value is the district
print "$state\n";
}
The state name code is as follows:
if ($line =~ m/^State:,(\w+\s\w+),/){
$state_name = $1;
$stat->{$year}->{$state_name} = {};
}
Any other way via which I can get individual values or I need to assign it to another hash and so forth. Thank you.

To step through your structure properly, you need a loop more like this:
while (my ($year, $year_ref) = each(%$stat) )
{
while (my ($state, $state_ref) = each(%$year_ref) )
{
print "year = $year, state = $state\n";
}
}
You can add additional levels of loop below that if you want to iterate through the entire structure to flatten it.
For example, since you have five levels in your structure, and the level just below the last is an array reference:
while (my ($year, $year_ref) = each(%$stat) )
{
while (my ($state, $state_ref) = each(%$year_ref) )
{
while (my ($city, $city_ref) = each(%$state_ref) )
{
foreach my $prod_rec ( #$city_ref )
{
while (my ($prod, $qty) = each(%$prod_rec) )
{
print "year = $year, state = $state, city = $city, prod = $prod, qty = $qty\n";
}
}
}
}
}
(Please forgive me if I guessed wrong naming the level under $state as $city. It is just a guess.)

Learn how to "walk" through the nested hashes/array. Check below code.
#!/usr/bin/perl
use warnings;
use strict;
my $VAR1 = {
'2001' => {
'Arunachal Pradesh' => {
'CHANGLANG' => [
{
'wheat' => '2',
'cotton' => '',
'rice' => '1'
}
],
'SUBANSIRI UPPER' => [
{
'wheat' => '',
'cotton' => '1',
'rice' => '2'
}
],
},
'Andhra Pradesh' => {
'CHITTOOR' => [
{
'wheat' => '34',
'cotton' => '14',
'rice' => '27'
}
],
'VIZIANAGARAM' => [
{
'wheat' => '2',
'cotton' => '',
'rice' => '8'
}
],
}
}
};
foreach my $a (keys %{ $VAR1->{2001} })
{
print $a."\n";
foreach my $b (keys %{ $VAR1->{2001}->{$a} })
{
print "\t".$b."\n";
foreach my $c ( #{ $VAR1->{2001}->{$a}->{$b} })
{
#print $c."\n";
foreach my $d ( keys %{ $c })
{
print "\t\t $d ===> $c->{$d} \n";
}
}
}
}
OutPut:
Arunachal Pradesh
CHANGLANG
rice ===> 1
wheat ===> 2
cotton ===>
SUBANSIRI UPPER
rice ===> 2
wheat ===>
cotton ===> 1
Andhra Pradesh
CHITTOOR
rice ===> 27
wheat ===> 34
cotton ===> 14
VIZIANAGARAM
rice ===> 8
wheat ===> 2
cotton ===>
In above code, I am hitting each and every element of the hash and printing it manually. This way you can capture any element in the hash and then use it later.

Related

Import Json data from url and save it to database laravel

i have this json data come from a url:
[
{
"id": "4070",
"title": "Speedway Racing",
"description": "Drivers start your engines! Professional oval track racing that explodes with stock car racing action!",
"instructions": "Use WASD or Arrow keys to move the car ",
"url": "https://html5.gamemonetize.com/b7dzsckxzmy5z3to54nif435exdiogkz/",
"tags": "Car, Cars, Racing",
"thumb": "https://img.gamemonetize.com/b7dzsckxzmy5z3to54nif435exdiogkz/512x384.jpg",
"width": "960",
"height": "600",
"category": "Driving"
},]
I need to save all data in database but for category i need to create new category from the category fled and save it in post_categry table (cat_id, post_id) if his not exists, also check f this game exists in db if yes ignore if no save it.
My GameController:
the json data come from this lik:
This link
public function importer_start(Request $request)
{
$game_cat = new Game;
$validatedata = $this->validate($request, [
'game_source' => 'required',
'source_url' => 'required|url',
]);
$dataurl = $request->input('source_url');
$sourve_name = $request->input('game_source');
$content = file_get_contents($dataurl);
$data = json_decode($content, true);
$query_ammount = $request->input('source_url');
parse_str($query_ammount, $params);
$game_amount = $params['amount'];
$query_ammount = $request->input('source_url');
parse_str($query_ammount, $params);
$game_amount = $params['amount'];
$url = $request->input('source_url');
$parmt_url = parse_url($url);
parse_str($parmt_url['query'], $params);
if ($params['format'] != 'json') {
toastr()->error('Please select JSON file to import games');
return redirect()->back();
}
if (#strpos($dataurl, Constants::GAMESOURCE_GAMEMONETIZE)) {
$finalarray = array();
foreach ($data as $key=>$value) {
// dd($value);
array_push($finalarray,array(
'game_id' => $value['id'],
'title' => $value['title'],
'description' => $value['description'],
'instructions' => $value['instructions'],
'url' => $value['url'],
'category' => !empty($value['category']) ? $value['category']: 'uncategorized',
'tags' => $value['tags'],
'thumb' => $value['thumb'],
'width' => $value['width'],
'height' => $value['height'],
'source' => Constants::GAMESOURCE_GAMEMONETIZE,
'views' => 15,
)
);
}
$categories[] = $value['category'];
Game::insert($finalarray);
toastr()->success('You have add '.$game_amount.' from '.\Constants::GAMESOURCE_GAMEMONETIZE.'');
return redirect()->route('admin.importer');
}elseif (#strpos($dataurl, Constants::GAMESOURCE_GAMEDISTRIBUTION)) {
$result = json_decode(json_encode($data), true);
$key = array_search('categoryList', array_column($result, 'categoryList'));
$finalarray = array();
foreach ($data as $key=>$value) {
array_push($finalarray,array(
'title' => $value['title'],
'gameType' => $value['gameType'],
'gameMobile' => $value['gameMobile'],
'mobileMode' => $value['mobileMode'],
'instructions' => $value['instructions'],
'description' => $value['description'],
'width' => $value['width'],
'height' => $value['height'],
'url' => $value['url'],
'source' => Constants::GAMESOURCE_GAMEDISTRIBUTION,
'assetList' => json_encode($value['assetList']),
'tagList' => json_encode($value['tagList']),
'category' => $value['categoryList'][0]['name'],
'views'=> 15,
)
);
}
//dd($finalarray);
Game::insert($finalarray);
toastr()->success('You have add '.$game_amount.' from '.\Constants::GAMESOURCE_GAMEDISTRIBUTION.'');
return redirect()->route('admin.importer');
}
}
Laravel version: 7.0
Thank you for your helpe.

JSON sort by specific value - PERL

i have this example code
#!/usr/bin/perl
use strict;
use warnings;
use JSON::PP qw( );
use Data::Dumper qw (Dumper);
my $json = JSON::PP->new()->pretty->utf8; # lesbares JSON | Sort numerically
my %ORDER = (id => 1, name => 2);
$json->sort_by(sub {
($ORDER{$JSON::PP::a} // 999) <=> ($ORDER{$JSON::PP::b} // 999)
or $JSON::PP::a cmp $JSON::PP::b
});
print $json->encode(
[
{name => 'ABS700', id => 0, data => [
{
dmsg => 's4F038300', state => 'T: 3.3', user => 'SD_Protocol'
}
]
},
{name => 'GT-WT-02', id => 0, data => [
{
dmsg => 's5410AC5F9800', state => 'T: 17.2 H: 47', user => 'Ralf9'
}
]
},
{name => 'NEU', id => 99, data => [
{
dmsg => 's5410AC5F9800', state => 'T: 17.2 H: 47', user => 'NEUER'
}
]
},
{name => 'Ventus W132', id => 4, data => [
{
dmsg => 'sD66EE1603000', user1 => 'dirigent', comment => 'wind',
readings => [{ state => 'windGuest: 1.2 winddir:0' }]
}
]
},
],
);
I would like to sort this, that the value with the "id => 99" appears at the end.
I could sort all internal values ​​arbitrarily but I need the new outer sorting.
How do I solve this problem?
->sort_by is used to control the order of the elements of hashes.
You want to control the order of the elements of an array.
There's no equivalent mechanism to ->sort_by for arrays because there's no need for one. While you can't naturally control the order in which a hash returns its elements, you can naturally control the order in which an array returns its elements.
my $data = [ ... ];
#$data = sort { $a->{id} <=> $b->{id} } #$data;
print $json->encode($data);

Parse JSON-like markup in perl

I am not sure what markup this is to be honest, I though at first JSON but using parse_json from JSON::Parse fails with: JSON error at line 2, byte 15/1380740: Unexpected character '{' parsing initial state: expecting whitespace: '\n', '\r', '\t', ' ' at ....
This is what I parse into an hash: https://steamcdn-a.akamaihd.net/apps/730/scripts/items/items_game.d8a302f03758b99ab65b60b3a4a11d73ca4738bd.txt.
What I tried:
use strict;
use warnings;
use LWP::UserAgent;
use JSON::Parse 'parse_json';
my $ua = LWP::UserAgent->new;
my $response = $ua->get( "https://steamcdn-a.akamaihd.net/apps/730/scripts/items/items_game.d8a302f03758b99ab65b60b3a4a11d73ca4738bd.txt" );
if ( $response->is_success ) {
my $game_items = parse_json( $response->content );
# ... do stuff
}
Am I doing something wrong? Is this JSON or must I create some hack-ish solution to parse this?
I could not find any suggestions through the "Questions that may already have your answer" section though I think it would be easier if I knew the name of this markup.
This will process your data, It's a bit hacky but it does the job!
use strict;
use warnings;
use autodie;
use Data::Dump;
use LWP::Simple qw/ mirror /;
use constant URL => 'https://steamcdn-a.akamaihd.net/apps/730/scripts/items/items_game.d8a302f03758b99ab65b60b3a4a11d73ca4738bd.txt';
use constant MIRROR => 'steamcdn.txt';
my $data = do {
mirror URL, MIRROR;
open my $fh, '<', MIRROR;
local $/;
<$fh>;
};
my ($hash, $key);
my #stack;
while ( ) {
if ( $data =~ / \G \s* " ([^"]*) " /gcx ) {
if ( defined $key ) {
$hash->{$key} = $1;
$key = undef;
}
else {
$key = $1;
}
}
elsif ( $data =~ / \G \s* \{ /gcx ) {
push #stack, [ $hash, $key ];
$key = $hash = undef;
}
elsif ( $data =~ / \G \s* \} /gcx ) {
die "Structure unbalanced" if defined $key or #stack == 0;
my ($parent, $key) = #{ pop #stack };
$parent->{$key} = $hash;
$hash = $parent;
}
else {
last;
}
}
die "Structure unbalanced" if #stack;
dd $hash;
output
{
items_game => {
alternate_icons2 => {
weapon_icons => {
65604 => {
icon_path => "econ/default_generated/weapon_deagle_hy_ddpat_urb_light",
},
65605 => {
icon_path => "econ/default_generated/weapon_deagle_hy_ddpat_urb_medium",
},
65606 => {
icon_path => "econ/default_generated/weapon_deagle_hy_ddpat_urb_heavy",
},
65684 => {
icon_path => "econ/default_generated/weapon_deagle_aa_flames_light",
},
65685 => {
icon_path => "econ/default_generated/weapon_deagle_aa_flames_medium",
},
65686 => {
icon_path => "econ/default_generated/weapon_deagle_aa_flames_heavy",
},
65696 => {
icon_path => "econ/default_generated/weapon_deagle_so_night_light",
},
65697 => {
icon_path => "econ/default_generated/weapon_deagle_so_night_medium",
},
65698 => {
icon_path => "econ/default_generated/weapon_deagle_so_night_heavy",
},
65780 => {
icon_path => "econ/default_generated/weapon_deagle_aa_vertigo_light",
},
65781 => {
icon_path => "econ/default_generated/weapon_deagle_aa_vertigo_medium",
},
65782 => {
icon_path => "econ/default_generated/weapon_deagle_aa_vertigo_heavy",
},
65896 => {
icon_path => "econ/default_generated/weapon_deagle_hy_mottled_sand_light",
},
65897 => {
icon_path => "econ/default_generated/weapon_deagle_hy_mottled_sand_medium",
},
65898 => {
icon_path => "econ/default_generated/weapon_deagle_hy_mottled_sand_heavy",
},
66276 => {
icon_path => "econ/default_generated/weapon_deagle_am_scales_bravo_light",
},
66277 => {
icon_path => "econ/default_generated/weapon_deagle_am_scales_bravo_medium",
},
66278 => {
my $file = do { local $/; <> };
my #stack = [];
my %handlers = (
'"' => sub {
/\G ([^"]*) " /xgc
or die("Unterminated \"\n");
push(#{ $stack[-1] }, $1);
},
'{' => sub {
die("Expected string\n") if #{ $stack[-1] } % 2 == 0;
push(#stack, []);
},
'}' => sub {
die("Unmatched \"}\"\n") if #stack == 1;
my $hash = pop(#stack);
die("Missing value\n") if #$hash % 2 == 1;
push(#{ $stack[-1] }, { #$hash });
},
);
my $data;
for ($file) {
while (1) {
my $next_char = /\G \s* (\S) /gcx ? $1 : last;
my $handler = $handlers{$next_char}
or die("Unrecognized character \"$next_char\"\n");
$handler->();
}
die("Unmatched \"{\"\n") if #stack > 1;
my $hash = pop(#stack);
die("Missing value\n") if #$hash % 2 == 1;
$data = { #$hash };
}
Aside from a simpler stack than Borodin's and the use of a dispatch table instead of a long sequence of "if", this version provides proper error detection. This will detect truncated documents as well as unsupported features.

get all nodes from multi level hash in perl

I want all nodes of each key sorted by key in hash ref or array or something like so that I can iterate that according to my need since I have to display each key with its all children.
following is my data structure:
$hash1 = {
'3' => {
'title' => 'Parent-3',
'parentid' => '-1'
},
'1' => {
'children' => {
'11' => {
'title' => 'child-1',
},
'5' => {
'children' => {
'8' => {
'title' => 'first child of child-2',
},
'13' => {
'title' => 'second child of child-2',
}
},
'title' => 'child-2',
}
},
'title' => 'Parent-1',
'parentid' => '-1'
},
'2' => {
'title' => 'Parent-2',
'parentid' => '-1'
},
'4' => {
'title' => 'Parent-4',
'parentid' => '-1'
},
};
I have used following functions :
sub Options {
my $hash = shift;
my $options = '';
my $iter; $iter = sub {
my $hash = shift;
my $indent = shift || '';
foreach my $k (sort {$a <=> $b} keys %{$hash}) {
my $v = $hash->{$k};
if($v->{parentid} eq '-1'){
$options .= $v->{title} ."-parent\n";
}else{
$options .= $v->{title} . "," ;
}
if ($v->{children}){
$iter->($v->{children}, $indent . "");
}
}
chop($options);
$options .= "\n";
};
$iter->($hash);
return $options;
}
here it returns a string with comma separated but I need some kind of data structure so that I can able to find all children for each key (in the form of hash ref or array) like:
Parent-1 -> [child-1,child-2, first child of child-2, second child of child-2]
Parent-2
Parent-3
Parent-4
any one can help me out? thanks in advance.
If your only goal is to display the hash contents, you should use the Data::Dumper module. It can be used to print data structures of arbitrary complexity with a good format.
You may also find brian d foy's answer on checking key existence useful
The code for with code for walking a data structure and Data::Diver may give you all the help you need.

How to give additional parameters to DBIx search method to Schema class

I added new relationship to my Schema in Catalyst project:
__PACKAGE__->has_many(
'messageslog' => "myproject::Schema::Result::MessagesLog",
sub {
my $args = shift;
return {
"$args->{foreign_alias}.from" => "$args->{self_alias}.msisdn",
"$args->{foreign_alias}.service_id" => "3",
"$args->{foreign_alias}.date_time" => {between => ["2013-01-01 00:00:00", "2013- 01-05 23:59:59"]}
};
}
);
When I make request:
$c->model('DB::TableClass')->search({})->hashref_array;
it works perfectly.
But i need to insert search params like this:
__PACKAGE__->has_many(
'messageslog' => "myproject::Schema::Result::MessagesLog",
sub {
my $args = shift;
return {
"$args->{foreign_alias}.from" => "$args->{self_alias}.msisdn",
"$args->{foreign_alias}.service_id" => "$args->{params}->{id}",
"$args->{foreign_alias}.date_time" => {between => $args->{params}->{dates}}
};
}
);
$c->model('DB::TableClass')->search({}, {
join => 'messageslog',
-params => {id => 3, dates => ["2013-01-01 00:00:00", "2013-01-05 23:59:59"]}
})->hashref_array;
How can I do this?
By adding a method to the ResultSet instead of a relationship, see Cookbook/Predefined-searches.