Reformat json in a correct way - php

I have this php code as I am trying to execute a particular function in my php project, I code the implementation correct but I ran into a small problem.
<?php echo '<script type="text/javascript">';
$data = array(
'base' => 'USD',
'alter' => 'ETH',
'data' => array()
);
foreach ($cryptos as $row) {
$sy = $row["symbol"];
$data['data'][] = array(
"$sy" => [
"rate" => 1.552000000000000,
"min" => 1.0077600000000000,
"max" => 10.077600000000000,
"code" => $row["symbol"],
"dp" => 8
],
);
}
print_r("var fxCur = " . json_encode($data));
Running the code above I got this result below, That's the expected result but I want to omit [] between data
{
"base":"USD",
"alter":"ETH",
"data":[
{
"BTC":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"BTC",
"dp":8
}
},
{
"ETH":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"ETH",
"dp":8
}
}
]
}
But actually I wanted this result
{
"base":"USD",
"alter":"ETH",
"data":{
"BTC":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"BTC",
"dp":8
},
"ETH":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"ETH",
"dp":8
},
}
}

You're telling it to construct the data structure that way.
$data['data'][] = array(
"$sy" => [
...
]
);
That line says "append an element to $data['data'] at the next integer index and set it equal to the array e.g. [ "BTC" => [ ... ]]
I think what you want is:
$data['data'][$sy] = [
"rate" => 1.552000000000000,
"min" => 1.0077600000000000,
"max" => 10.077600000000000,
"code" => $row["symbol"],
"dp" => 8
];

Related

PHP Array and Updating an Array with data from another nested array [duplicate]

This question already has answers here:
How to extract and access data from JSON with PHP?
(1 answer)
How can I replace a specific key's value in an array in php?
(2 answers)
Closed 7 months ago.
I all, I've been staring at this for hours so any help is greatly appreciated. I have an array...
$aircraft = [
'N7826C' => ['nnum' => 'N7826C', 'name' => 'ANAHEIM POLICE DEPT', 'icon' => 'police', 'lat' => '', 'lng' => '', 'status' => '0'],
'N226PD' => ['nnum' => 'N226PD', 'name' => 'ANAHEIM POLICE DEPT', 'icon' => 'police', 'lat' => '', 'lng' => '', 'status' => '0'],
'N326PD' => ['nnum' => 'N326PD', 'name' => 'CITY OF ANAHEIM', 'icon' => 'police', 'lat' => '', 'lng' => '', 'status' => '0'],
'N826PD' => ['nnum' => 'N826PD', 'name' => 'CITY OF ANAHEIM', 'icon' => 'police', 'lat' => '', 'lng' => '', 'status' => '0']
];
With that array, I implode it to get a list of the nnums to pass through a API....
$aircraftNNUMlist = implode(',', array_map(function($v) { return $v['nnum']; }, $aircraft));
$json = file_get_contents('https://airlabs.co/api/v9/flights?_fields=reg_number,lat,lng&reg_number='.$aircraftNNUMlist.'&api_key=XXXXX');
That API returns...
{
"request": {
"lang": "en",
"currency": "USD",
"time": 15,
"id": "c9by9lmq1q0",
"server": "z",
"host": "airlabs.co",
"pid": 322387,
"key": {
"id": 19146,
"api_key": "xxxxxxxxxxxxxxxx",
"type": "free",
"expired": "2022-08-20T22:00:00.000Z",
"registered": "2022-07-19T03:51:04.000Z",
"limits_by_hour": 2500,
"limits_by_minute": 250,
"limits_by_month": 1000,
"limits_total": 628
},
"params": {
"_fields": "reg_number,lat,lng",
"reg_number": "N60NT,N40NT,N30NT,N10NT",
"lang": "en"
},
"version": 9,
"method": "flights",
"client": {
"ip": "xxxxxxxxxxxxxxxxx",
"geo": {
"country_code": "US",
"country": "United States",
"continent": "North America",
"city": "Provo",
"lat": 40.2181,
"lng": -111.6133,
"timezone": "America/Denver"
},
"connection": {
"type": "corporate",
"isp_code": 46606,
"isp_name": "Unified Layer"
},
"device": {},
"agent": {},
"karma": {
"is_blocked": false,
"is_crawler": false,
"is_bot": false,
"is_friend": false,
"is_regular": true
}
}
},
"response": [
{
"reg_number": "N60NT",
"lat": 34.11,
"lng": -117.69
}
],
"terms": "Unauthorized access is prohibited and punishable by law. \nReselling data 'As Is' without AirLabs.Co permission is strictly prohibited. \nFull terms on https://airlabs.co/. \nContact us info#airlabs.co"
}
I am having trouble looping through the "response" of the API return (stored at $json) to update the corresponding index in $aircraft. If a nnum isn't currently active there will not be a entry in "response" for instance "response" only has N60NT in the return array. I am fairly new to arrays so I've been taking swings in the dark and nothing seems to be right.
I presume you have json_decoded your api json response into a PHP array. Well actually:
$arr = json_decode($json_form_api, true);
$response = $arr["response"];
foreach ($response as $sub) {
$reg = $sub["reg_number"];
$aircraft[$reg]["lat"] = $sub["lat"];
$aircraft[$reg]["lng"] = $sub["lng"];
}

add values ​from a collection to others using a column as a reference (PHP, LARAVEL)

I am working with php in laravel, in this case I have 2 collections of objects, one of them looks like this:
[
{
"id": 1,
"name": "product x",
"quantity": "100",
},
{
"id": 2,
"codProd": "product y",
"quantity": "200",
},
{
"id": 3,
"name": "product a.",
"quantity": "30",
}
]
and the other looks like this:
[
{
"reference": 1,
"quantity": "80",
},
{
"reference": 2,
"quantity": "50",
},
]
What I need is to keep the first collection but adding the value of the quantity key from the second collection, using the reference key as a relationship with the id of the first collection, the final result should look like this:
[
{
"id": 1,
"name": "product x",
"quantity": "180",
},
{
"id": 2,
"codProd": "product y",
"quantity": "250",
},
{
"id": 3,
"name": "product a.",
"quantity": "30",
}
]
so how can I do this?, any guide or help I am grateful
You can use a collection method for this, the map method:
$collection_one = collect([
[
'id' => 1,
'name' => 'product x',
'quantity' => 100,
],
[
'id' => 2,
'name' => 'product y',
'quantity' => 100,
],
[
'id' => 1,
'name' => 'product a.',
'quantity' => 30,
],
]);
$collection_two = collect([
[
'reference' => 1,
'quantity' => 80,
],
[
'reference' => 2,
'quantity' => 50,
],
]);
For you to get the collection what you want:
$collect = [];
$collect = $collection_one->map(function ($value_one) use ($collection_two) {
if ($search = $collection_two->firstWhere('reference', '=', $value_one['id'])) {
$value_one['quantity'] += $search['quantity'];
}
return $value_one;
});
Ready, that worked for me. :)

Laravel 5.5 API Resource Collection using array

I am using laravel 5.5 API resource collection for showing list of products. I am using an array instead of the modal object. I got my list of items but i am not sure how to show item variant array in the response. The actual response array passing to the api resource are:
{
"ID": 3160,
"UserID": 3302,
"ItemName": "2",
"Description": "2",
"Price": 2,
"StockLimited": true,
"StockQuantity": 19,
"CurrencyCode": "USD",
"ImageUrl": "/images/items/Item3302-636434761494584365-qq5HFm.png",
"VariantItems": [
{
"ID": 3181,
"ItemName": "2",
"Price": 0,
"StockLimited": false,
"StockQuantity": 0,
"CurrencyCode": "USD",
"Variants": [
{
"Id": 1099,
"Name": "Red",
"VariantGroupId": 1027,
"VariantGroupName": "Colour"
},
{
"Id": 1111,
"Name": "S",
"VariantGroupId": 1028,
"VariantGroupName": "Size"
}
]
},
{
"ID": 3182,
"ItemName": "2",
"Price": 0,
"StockLimited": false,
"StockQuantity": 0,
"CurrencyCode": "USD",
"Variants": [
{
"Id": 1099,
"Name": "Red",
"VariantGroupId": 1027,
"VariantGroupName": "Colour"
},
{
"Id": 1112,
"Name": "M",
"VariantGroupId": 1028,
"VariantGroupName": "Size"
}
]
}
],
"MerchantName": "seller",
"VariantGroupLists": [
{
"VariantGroupName": "Colour",
"Names": [
"Red",
"Grey",
"Navy"
]
},
{
"VariantGroupName": "Size",
"Names": [
"S",
"M",
"L",
"XL"
]
}
]
}
My ItemResourceCollection
public function toArray($request)
{
return [
'data' => $this->collection->map(function ($item) use ($request) {
return (new ItemResource($item))->toArray($request);
})
];
}
My ItemResource
public function toArray($request)
{
return [
"item_id" => $this->resource->ID,
"item_name" => $this->resource->ItemName,
"description" =>$this->resource->Description,
"item_price"=>$this->resource->Price,
"stock_qty"=>$this->resource->StockQuantity,
"currency_code"=>$this->resource->CurrencyCode,
"item_image_url"=>$this->resource->ImageUrl,
];
}
public function with($request)
{
return ['item_varients' => [new ItemResource($this->resource->VariantItems)]];
}
What I am trying to achieve is this result:
[
{
"item_id": 3160,
"item_name": "BLACK COWL NECK DRESS WITH DIAMANTE DETAIL",
"description": "Test test",
"item_price": 16.99,
"stock_qty": 20,
"currency_code": "SGD",
"item_image_url": "/images/items/Item18-636231488325192562-GoiIBl.png",
"item_varients": [
{
"id": 29,
"name": "Red",
"varientgroupId": 11,
"varientgroupname": "Color"
}
]
}
]
the with() method in ItemResource is not working. How do I add the "item_varients" array in the resource response?
I would first move the line to add the item_varients property inside the method toArray like following:
public function toArray($request)
{
return [
"item_id" => $this->resource->ID,
"item_name" => $this->resource->ItemName,
"description" => $this->resource->Description,
"item_price" => $this->resource->Price,
"stock_qty" => $this->resource->StockQuantity,
"currency_code" => $this->resource->CurrencyCode,
"item_image_url" => $this->resource->ImageUrl,
"item_varients" => [
new ItemResource($this->resource->VariantItems)
]
]
}
Meta information
We do that because the with is meant for to add a meta information block or something similar. See https://laravel.com/docs/5.5/eloquent-resources#adding-meta-data
The advantage when using the with method is, that multiple resources results in only one meta block. This is not what you want, I think.
Resource for VariantItem
I think you have to build a Resource class also for VariantItem. And because the VariantItems are a collection you also have to fill your array called item_variants similar to your ItemResourceCollection. So change your code to look like this:
public function toArray($request)
{
/**
* Prepare your variant items to have a collection
*
* #var Collection $variantItems
*/
$variantItems = collect($this->resource->VariantItems);
return [
"item_id" => $this->resource->ID,
"item_name" => $this->resource->ItemName,
"description" => $this->resource->Description,
"item_price" => $this->resource->Price,
"stock_qty" > $this->resource->StockQuantity,
"currency_code" => $this->resource->CurrencyCode,
"item_image_url" => $this->resource->ImageUrl,
"item_varients" => VariantItem::collection($variantItems)
]
}
Here is the best way to get specific fields using a collection
return [
'id' => $this->id,
'variant_item' => new CustomResource($this->user, ['item_id', 'item_name', 'item_size'])
];

How to combine bool must and sort for elasticsearch

i am trying to sort some data, where in my base skeleton my sorting is not working and if i remove the sorting it works fine.
So how can i put sorting in my base skeleton and sort some data.
i can't put just
$params['body'] = [
'sort' => [['title' => ['order' => 'asc']]]];
$results = $client->search($params);
Because i have other condition where i need the must condition.
Can anyone knows how it can be solve.
Any advice will be really appreciate.
// my base skeleton
$params = array(
'index' => "myIndex",
'type' => "myType",
'body' => array(
'query' => array(
'bool' => array(
'must' => array(
// empty should clause for starters
)
)
),
'sort' => array()
)
);
// sorting is not working with bool and must
if ($request->request->get('salarySort')) {
$params['body']['query']['bool']['must'][] = array(
'sort' => array(
"title" => array('order' => 'asc')
)
);
}
this is what i get as a json_encode ---
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1066,
"max_score": null,
"hits": [
{
"_index": "myIndex",
"_type": "myType",
"_id": "pe065319de73937aa6ef46413afd7aac26a58a611",
"_score": null,
"_source": {
"title": "Smarason trycker ",
"content": "HIF gör 2-0 mot Halmstad.",
"tag": [
"Soprts"
],
"category": [
"Sports"
]
},
"sort": [
"0"
]
},
{
"_index": "myIndex",
"_type": "myType",
"_id": "pebc44a70008f53f74f23ab23f8a1f79b2b729448",
"_score": null,
"_source": {
"title": "Anders Svenssons tips gav 1-0",
"content": "Anders Svenssons tips i halvtid Kalmar FF.",
"source": "Unknown",
"tag": [
"Soprts"
],
"category": [
"Sports"
]
},
"sort": [
"0"
]
}
]
}
}
query in JSON ---
{
"index": "myIndex",
"type": "myType",
"size": 30,
"body": {
"query": {
"match_all": []
},
"sort": [
{
"title": "asc"
}
]
}
}
You're almost there. You've correctly placed the empty sort array at the same level as your query, which is correct.
The issue comes later when you try to feed it as a bool/must constraint instead of in the empty sort array.
// sorting is not working with bool and must
if ($request->request->get('salarySort')) {
$params['body']['sort'][] = array( <---- this line needs to be changed
"Salary" => 'asc' <---- this line needs to be changed, too
);
}

I can not get data to aggregate It. PHP + mongoDB

It works like I need:
$out = $collection->aggregate(
array(
'$match' => array('type' => 'chair')
),
array(
'$project' => array(
'chairtype' => 1,
'mijczjeqeo'=>1
)
),
array(
'$group' => array(
'_id' => '$chairtype',
'MIDDLE_mijczjeqeo' => array('$avg' => '$mijczjeqeo'),
'SUMMA__mijczjeqeo' => array('$sum' => '$mijczjeqeo')
)
)
);
my_dump($out);
But i need to get true data for aggregation from array in the same documents: versions[0][content][mijczjeqeo]
Please correct my script. It does not work:
$out = $collection->aggregate(
array(
'$match' => array('type' => 'chair')
),
array(
'$project' => array(
'chairtype' => 1,
'versions.0.content.mijczjeqeo'=>1
)
),
array(
'$group' => array(
'_id' => '$chairtype',
'MIDDLEmijczjeqeo' => array('$avg' => '$versions.0.content.mijczjeqeo'),
'SUMMAmijczjeqeo' => array('$sum' => '$versions[0]["content"]["mijczjeqeo"]')
)
)
);
no one method does not work:
'MIDDLEmijczjeqeo' => array('$avg' => '$versions.0.content.mijczjeqeo')
'SUMMAmijczjeqeo' => array('$sum' => '$versions[0]["content"]["mijczjeqeo"]')
I think the problem near .0.
I try to do it in mongo console...
db.documents.aggregate({$match:{'type':'chair'}},{$project:{'chairtype': 1, 'mijczjeqeo':1}},{$group:{'_id':'$chairtype','MID':{$avg:'$mijczjeqeo'}}})
{
"result" : [
{
"_id" : "T",
"MID" : 6.615384615384615
},
{
"_id" : "G",
"MID" : 8.310344827586206
},
{
"_id" : "E",
"MID" : 6.9523809523809526
}
],
"ok" : 1
}
db.documents.aggregate({$match:{'type':'chair'}},{$project:{'chairtype': 1, 'versions.0.content.mijczjeqeo':1}},{$group:{'_id':'$chairtype','MID':{$avg:'$versions.0.content.mijczjeqeo'}}})
{
"result" : [
{
"_id" : "T",
"MID" : 0
},
{
"_id" : "G",
"MID" : 0
},
{
"_id" : "E",
"MID" : 0
}
],
"ok" : 1
}
Well you cannot project like that in the aggregation pipeline. If you want to act on array elements within an aggregation statement you first need to $unwind the array and then either $match the required element(s) or as in your case choose the $first item using an additional $group stage.
Your question does not show the structure of a document so I'll just use a sample, as my "chairs" collection:
{
"_id": 1,
"type": "chair",
"chairtype": "A",
"versions": [
{
"revision": 1,
"content": {
"name": "ABC",
"value": 10
}
},
{
"revision": 2,
"content": {
"name": "BBB",
"value": 15
}
}
]
}
{
"_id": 2,
"type": "chair",
"chairtype": "A",
"versions": [
{
"revision": 1,
"content": {
"name": "CCC",
"value": 20
}
},
{
"revision": 2,
"content": {
"name": "BAB",
"value": 12
}
}
]
}
Minimal, but enough to get the point. Now the aggregate statement:
db.chairs.aggregate([
// Normal query matching, which is good
{ "$match": { "type": "chair" } },
// Unwind the array to de-normalize
{ "$unwind": "$versions" },
// Group by the document in order to get the "first" array element
{ "$group": {
"_id": "$_id",
"chairtype": { "$first": "$chairtype" },
"versions": { "$first": "$versions" }
}},
// Then group by "chairtype" to get your average values
{ "$group": {
"_id": "$chairtype",
"MID": {"$avg": "$versions.content.value"}
}}
])
Of course if your actual document has nested arrays then you will be "unwinding" and "matching" the required elements. But that is the general process of "narrowing down" the array contents to the elements you need.

Categories