JSON sort by specific value - PERL - json

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);

Related

How to store some columns as Json data after importing an excel file using maatwebsite

I need to import an excel file which has Name, Email, Phone_number, Department, Division and some more dynamic columns.
IFile import code:
$file = $request->file('file');
$location = 'uploads';
$filename = $file->getClientOriginalName();
$file->move($location, $filename);
$filepath = public_path($location . "/" . $filename);
$items = \Excel::toArray(new EmployeesImport(), $filepath);
dd($items);
After importing an excel file,I get an array as this:
array:1 [
0 => array:3 [
0 => array:5 [
"name" => "ABC"
"email" => "ashadpeal71#gmail.com"
"phone_number" => 1863184077
"department" => "IT"
"division" => "S/W"
]
1 => array:5 [
"name" => "DEF"
"email" => "ashadpeal72#gmail.com"
"phone_number" => 1671536101
"department" => "Business"
"division" => "Marketing"
]
2 => array:5 [
"name" => "GHI"
"email" => "ashadpeal73g#gmail.com"
"phone_number" => 184325432
"department" => "Transport"
"division" => "Bus"
]
]
]
employees table has name``email``phone_number and meta_data(json) field.
How can I store Division, Department and some dynamic columns in meta_data field as json data?
Please help me to find a solution.
First, add WithHeadingRow. To use heading row (1st row) as array keys of each row :
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class UsersImport implements WithHeadingRow...
And then,
$items = \Excel::toArray(new UsersImport(), $filepath);
foreach($items[0] as $item){
$name = $item['name'];
array_shift($item);
YourModel::create([
'name' => $name,
'meta_data' => $item
]);
}
PS : Don't forget to use array cast. array cast is particularly useful when working with columns that are stored as serialized JSON.
class YourModel extends Model
{
protected $casts = [
'meta_data' => 'array',
];
...
}
I've found my solution by adding this code-
foreach($items[0] as $item){
$name = $item['name'];
$email = $item['email'];
$phone_number = $item['phone_number'];
$remove = ['name', 'email', 'phone_number'];
$meta_data= array_diff_key($item, array_flip($remove));
$password = (\Str::random(8));
User::create([
'name' => $name,
'email' => $email,
'phone_number' => $phone_number,
'meta_data' => $meta_data,
'password' => \Illuminate\Support\Facades\Hash::make($password),
]);
}
Hope someone will be benefited.

Laravel - How to sort external API in desc order and select set of records

In my Laravel-8, I am getting external API using Guzzle:
I got this set of records for dd($json) in the Controller:
array:554 [▼
0 => array:30 [▼
"PartitionKey" => "19SB22"
"RowKey" => "0000"
"Timestamp" => "2021-01-22T12:30:25.4698261Z"
"client_tracking_id" => "ddd3321"
"current_asset_position_name" => "2, Adelaide, Australia"
"service_tracking_id" => "19SB22"
"this_tracking_job_id" => "0000"
"trip_status" => "DISPATCHED"
]
1 => array:31 [▼
"PartitionKey" => "19SB22"
"RowKey" => "2233"
"Timestamp" => "2021-02-23T20:51:50.3066741Z"
"client_tracking_id" => "TRIP-20200621007"
"current_asset_position_name" => "20, Adelaide, Australia"
"service_tracking_id" => "19SB22"
"this_tracking_job_id" => "19SB22"
"trip_status" => "AROUND CUSTOMER LOCATION"
]
....
Here is the Controller:
public function index() {
$client = new Client();
$res = $client->request('GET','https://example.com/api/tracking/19SB22', [
'query' => ['key' => 'jkkmkf']
])->getBody();
$json = json_decode($res->getContents(), true);
return view('welcome', [
'json' => $json,
]);
How do I sort the result $json in descending order using Timestamp field and select the first set of record?
Thanks
Use Collections and Carbon to convert the date string into a correct timestamp.
Collections are laravels array extension, that makes it possible to do function calls on collections (arrays). There is an sortBy() and sortyByDesc() functions, these can be used and using Carbon::parse(), that should be able to parse your zulu date. After that you can use first() to get your element.
$firstElement = collect($yourData)->sortByDesc(function ($data) {
return Carbon::parse($data['Timestamp'])->timestamp;
})->first();

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.

order not working with sortWhitelist

Using CakePHP 3.5.3
Hi,
The below code works works as it should and displays the result set and orders it by the due_date asc.
public $paginate = [
'limit' => 5,
'order' => [
'Activities.due_date' => 'asc'
]
];
public function index()
{
$session = $this->request->session();
// Declare client id 1
$cidOne = null;
$cidOne = $session->read('Cid.one');
// NOTE* DON'T USE ORDER HERE BECAUSE THE SORTS WILL NOT WORK
$query = $this->Activities->find('all')
->where(['cid_1' => $cidOne])
->andWhere(['status' => 1]);
// Send the query to the view.
$this->set('activities', $this->paginate($query));
}
But when I add sortWhitelist as below the initial page load is not sorted by the due_date and no sort arrow is displayed.
public $paginate = [
'sortWhitelist' => [
'due_date', 'related_to', 'subject', 'post_code', 'type', 'priority'
],
'limit' => 5,
'order' => [
'Activities.due_date' => 'asc'
]
];
Thanks for any help. Z.
There must be consistency between the sortWhitelist array, the order array and the paginator link
so if your field is Activities.due_date your code becomes:
public $paginate = [
'sortWhitelist' => [
'Activities.due_date', 'related_to', 'subject', 'post_code', 'type', 'priority'
],
'limit' => 5,
'order' => [
'Activities.due_date' => 'asc'
]
];
and in your view
<?= $this->Paginator->sort('Activities.due_date', __('Due Date')) ?>
If there is no ambiguity in the fields names you can omit the Model name and simply use due_date as column name

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.