Arrange items based on product id - php

In the JSON file, there are multiple item based on the same product_id. I have to create multidimensional array based on product_id and items.
As per my sample php code, product_id is repeatedly listing. Results are printed in php code.
Expecting results are given below.
testData.json
"data": [
{
"product_id": "123456",
"item": "ZAD",
"time": "15:30",
"quantity": 1
},
{
"product_id": "24534"
"item": "REST"
"time": "5:30"
"quantity": 1
},
{
"product_id": "123456"
"item": "RAD"
"time": "10:30"
"quantity": 2
}
]
test.php
$json = file_get_contents('testData.json');
$d_data = json_decode($json, true);
$f_data = $d_data['data'];
foreach($f_data as $data) {
$result = [
$data['product_id'],
$data['item']
]
print_r($result);
/* Array(
[0] => 123456
[1] => ZAD
)
Array(
[0] => 123456
[1] => RAD
)
Array(
[0] => 24534
[1] => REST
)
*/
}
Expecting Result
123456
[
ZAD
[
"time" => "15:30",
"quantity" => 1
],
RAD
[
"time" => "10:30"
"quantity" => 2
],
],
24534
[
REST
[
"time" => "5:30"
"quantity" => 1
]
]

You just need to account for both product_id and item as sub-keys in the final array:
$result = [];
foreach($f_data as $data) {
$result[$data['product_id']][$data['item']] = [
$data['time'],
$data['quantity']
];
}
print_r($result);
Demo: https://3v4l.org/sf7om
I should note, if two items have the same product_id and same item, this code will only keep the last one. If that scenario applies to you, you just need to use the append mode ([]) of the array:
$result[$data['product_id']][$data['item']][] = [
$data['time'],
$data['quantity']
];

Related

Group rows of data by a column value and restructure into an associative multi-dimensionsl array

I am trying to change an indexed array of arrays into a new array structure. My data is as follows:
$arr = array(
array( "year" => 1921, "name" => "bob" ),
array( "year" => 1944, "name" => "steve" ),
array( "year" => 1944, "name" => "doug" ),
array( "year" => 1921, "name" => "jim" ),
);
I would like to recreate a new array thats groups them into the same year. The best I can come up with is designating the year as the key so any row that has that year gets added to that key, but it's not the output that I'm looking for. What I need is how it's listed below.
"data": [
{
"year":"1921",
"names": [
{ "name":"bob" }, { "name":"jim"}
]
},
{
"year":1944",
"names": [
{ "name":"steve" }, { "name":"doug "}
]
}
You don't need to pre-extract the unique years nor use conditions within nested loops. Just push the data into the result set using temporary first-level keys, then remove the temporary keys when finished looping.
This ensures unique years, but allows names to be duplicated.
Code: (Demo)
$arr = [
["year" => 1921, "name" => "bob"],
["year" => 1944, "name" => "steve"],
["year" => 1944, "name" => "doug"],
["year" => 1921, "name" => "jim"],
];
foreach ($arr as $item) {
$result[$item['year']]['year'] = $item['year'];
$result[$item['year']]['names'][] = ['name' => $item['name']];
}
echo json_encode(
['data' => array_values($result)],
JSON_PRETTY_PRINT // for better visualization
);
Output:
{
"data": [
{
"year": 1921,
"names": [
{
"name": "bob"
},
{
"name": "jim"
}
]
},
{
"year": 1944,
"names": [
{
"name": "steve"
},
{
"name": "doug"
}
]
}
]
}

convert json to object php

I just learned php
I have a separate database table, and I want to combine that table with only 1 parameter with JSON output, but the resulting output is wrong, how to change my JSON to json which is correct and easy to use.
thanks
json output :
[
[
{
"id_service": "3",
"reference_number": "",
"tracking_number": "RJC-0000-0001",
"kd_inbound": "INB-1000-0001",
"tgl_inbound": "2019-11-07 00:00:00",
"status_inb": "1"
}
],
[
{
"id_service": "3",
"reference_number": "",
"kd_outbag": "BAG-1468-0002",
"tanggal_outbag": "2019-11-07 00:00:00",
"status_outbag": "1"
}
],
[
{
"id_service": "3",
"reference_number": "",
"kd_outbound": "OTB-1826-0001",
"tgl_outbound": "2019-11-07 17:04:49",
"status_otb": "1"
}
],
]
this my code
public function awb_get() {
$id = $this->get('tracking_number');
$res= array(
$this->M_tarif->tampil_status_inbound($id),
$this->M_tarif->tampil_status_otboundbag($id),
$this->M_tarif->tampil_status_otboundori($id),
$this->M_tarif->tampil_status_indes($id),
$this->M_tarif->tampil_status_outdes($id),
$this->M_tarif->tampil_status_runsheet($id),
$this->M_tarif->tampil_db_service_status($id)
);
$this->response($res, 200);
}
i want in like this
{
"status": 200,
"error": false,
"awb": [
{
"tracking_number": "RJC-0000-0004",
"status": "order",
"tanggal": "2019-10-30"
},
{
"tracking_number": "RJC-0000-0004",
"status": "Inbound to origin",
"tanggal": "2019-11-03"
}
]
}
Your json response is not correct.
So, first you have to reset your JSON before send to function. I was make sample to rearrange JSON and convert it in stdClass Object. Please check below code to convert with your response.
$arr ='[
[
{
"id_service": "3",
"reference_number": "",
"tracking_number": "RJC-0000-0001",
"kd_inbound": "INB-1000-0001",
"tgl_inbound": "2019-11-07 00:00:00",
"status_inb": "1"
}
],
[
{
"id_service": "3",
"reference_number": "",
"kd_outbag": "BAG-1468-0002",
"tanggal_outbag": "2019-11-07 00:00:00",
"status_outbag": "1"
}
],
[
{
"id_service": "3",
"reference_number": "",
"kd_outbound": "OTB-1826-0001",
"tgl_outbound": "2019-11-07 17:04:49",
"status_otb": "1"
}
],
]';
$result = str_replace(array('[',']','\n'), '',htmlspecialchars(json_encode($arr), ENT_NOQUOTES));
$str = preg_replace('/\\\"/',"\"", $result);
$json = '[';
$json .= substr($str, 2,-1); // Substring -1 character from the end of the json variable, this will be the trailing comma.
$json .= ']';
$jsonData = preg_replace("/,(?!.*,)/", "", $json);
echo "<pre>";
print_r(json_decode($jsonData));
echo "</pre>";
output:
Array
(
[0] => stdClass Object
(
[id_service] => 3
[reference_number] =>
[tracking_number] => RJC-0000-0001
[kd_inbound] => INB-1000-0001
[tgl_inbound] => 2019-11-07 00:00:00
[status_inb] => 1
)
[1] => stdClass Object
(
[id_service] => 3
[reference_number] =>
[kd_outbag] => BAG-1468-0002
[tanggal_outbag] => 2019-11-07 00:00:00
[status_outbag] => 1
)
[2] => stdClass Object
(
[id_service] => 3
[reference_number] =>
[kd_outbound] => OTB-1826-0001
[tgl_outbound] => 2019-11-07 17:04:49
[status_otb] => 1
)
)

Create and fill an associative array of multiples dimensions

I'm currently trying to create an associative array which will have two dimensions and I think a solution for this probleme could resolve problemes for array with more dimensions.
I recover data with an API which look like that :
{
"item_id": "89",
"name": "Confiture de Myrtilles",
"product_id": "737",
"meta_key": "vmm_warehouse_sg_10783",
"meta_value": "0"
},
{
"item_id": "89",
"name": "Confiture de Myrtilles",
"product_id": "737",
"meta_key": "vmm_warehouse_sg_10782",
"meta_value": "0"
},
{
"item_id": "91",
"name": "Poires Guyot (bio)",
"product_id": "690",
"meta_key": "_backorders",
"meta_value": "no"
},
{
"item_id": "91",
"name": "Poires Guyot (bio)",
"product_id": "690",
"meta_key": "_sold_individually",
"meta_value": "no"
},
I just want to create an array like this :
array[item_id->[meta_key->meta_value]]
So I have to recover the item_id which will have the role of the secondth array and after put in this array the meta_key and meta_value associated.
So for example I will have an array like this :
Products[89]["vmm_warehouse_sg_10783"->"0"
"vmm_warehouse_sg_10782"->"0"]
And an other like this :
Products[91][........]
At the end, I will have a final array like this :
Products [ [89]->{"vmm_warehouse_sg_10783"->"0","vmm_warehouse_sg_10782"->"0"}
[91]->{.....}]
I have already tried something but I'm just a beginner and I don't found solution for my problem.
$Products = $this->wpdb->get_results( $SQL_Deliveries );
//this line allow $Products to recover all data from the API
foreach ( $Products as $Product ) {
$Meta_products[] = Product->item_id;
foreach($Product as $Product_meta){
$Meta_products[$item_id]->{Product_meta->meta_key,Product_meta
->meta_value);
}
I'm sure I did mitakes in my code too, but I really don't know how to resolve this problem. Thank you for your participation !
It looks like you want a multidimensional object array.
There is a little bit of fiddling involved to declare nested objects. The curly bracing is also necessary.
Code: (Demo)
$products = [
(object)["item_id" => "89",
"name" => "Confiture de Myrtilles",
"product_id" => "737",
"meta_key" => "vmm_warehouse_sg_10783",
"meta_value" => "0"
],
(object)["item_id" => "89",
"name" => "Confiture de Myrtilles",
"product_id" => "737",
"meta_key" => "vmm_warehouse_sg_10782",
"meta_value" => "0"
]
];
$result = (object)[];
foreach($products as $product) {
if (!isset($result->{$product->item_id})) {
$result->{$product->item_id} = (object)[];
}
$result->{$product->item_id}->{$product->meta_key} = $product->meta_value;
}
var_export($result);
Output:
(object) array(
'89' =>
(object) array(
'vmm_warehouse_sg_10783' => '0',
'vmm_warehouse_sg_10782' => '0',
),
)
Alternatively, to generate the nested object structure, you could build an array of arrays, then use json_encode(), then json_decode() on the result.
If you want an array as output, that's easiest:
Code: (Demo)
$products = [
(object)["item_id" => "89",
"name" => "Confiture de Myrtilles",
"product_id" => "737",
"meta_key" => "vmm_warehouse_sg_10783",
"meta_value" => "0"
],
(object)["item_id" => "89",
"name" => "Confiture de Myrtilles",
"product_id" => "737",
"meta_key" => "vmm_warehouse_sg_10782",
"meta_value" => "0"
],
(object)["item_id" => "91",
"name" => "Poires Guyot (bio)",
"product_id" => "690",
"meta_key" => "_backorders",
"meta_value" => "no"
],
(object)["item_id" => "91",
"name" => "Poires Guyot (bio)",
"product_id" => "690",
"meta_key" => "_sold_individually",
"meta_value" => "no"
]
];
$result = [];
foreach($products as $product) {
$result[$product->item_id][$product->meta_key] = $product->meta_value;
}
var_export($result);
Output:
array (
89 =>
array (
'vmm_warehouse_sg_10783' => '0',
'vmm_warehouse_sg_10782' => '0',
),
91 =>
array (
'_backorders' => 'no',
'_sold_individually' => 'no',
),
)
I don't fully understand what are you trying to achieve, but I suppose you want associative array with id as the key and array of meta_key and meta_value as its value?
If so, then:
foreach ( $Products as $Product ) {
$Meta_products[$Product->item_id][$Product->meta_key] = $Product->meta_value;
}

How to get the only first images in array inside array

Here i have one array(first array) inside i have one more array(second array), now i want to display only first image from second array(galleryImages) , how can do this. i tried but i am not able to get the results
print_r($response);
Array
(
[0] => stdClass Object
(
[gallery_id] => 2
[title] => Annual Day 2017
[description] =>
[galleryImages] => ["1.jpg","2.jpg","3.jpg","4.jpg"]
[reg_on] => 2017-05-17 01:55:12
[created_by] => rajeshdash123#gmail.com
[school_id] => 2
[status] => 0
)
[1] => stdClass Object
(
[gallery_id] => 3
[title] => Sports Day
[description] =>
[galleryImages] => ["1.jpg","2.jpg","3.jpg"]
[reg_on] => 2017-05-17 01:55:36
[created_by] => rajeshdash123#gmail.com
[school_id] => 2
[status] => 0
)
)
Expected Results
{
"status": "Success",
"data": [
{
"gallery_id": "2",
"title": "Annual Day 2017",
"description": "",
"galleryImagesCount": 4,
"gallery":"1.jpg"
},
{
"gallery_id": "3",
"title": "Sports Day 2017",
"description": "",
"galleryImagesCount": 4,
"gallery":"1.jpg"
}
],
}
I tried like this but is i am not getting the exact results
$images = array();
foreach ($response as $key => $value)
{
$img['gallery_id'] = $value->gallery_id;
$img['title'] = $value->title;
$img['description'] = $value->description;
$img['galleryImagesCount'] = count(json_decode($value->galleryImages,true));
$img['gallery'] = json_decode($value->galleryImages,true);
array_push($images,$img);
}
$return=array('status'=>"Success",'Images'=>$images);
echo json_encode($return);
Getting Results
{
"status": "Success",
"Images": [
{
"gallery_id": "2",
"title": "Annual Day 2017",
"description": "",
"galleryImagesCount": 4,
"gallery": [
"d17ac9d0aeb6435eaa294e0d69d4cc8f.jpg",
"a91945e0cf55379f51cf5faef10d7a4a.jpg",
"2d1501045ddbb3ccc238e70f9af05027.jpg",
"071c3b5f969bed1d1e2ee4b6531e4444.jpg"
]
},
{
"gallery_id": "3",
"title": "Sports Day",
"description": "",
"galleryImagesCount": 4,
"gallery": [
"f0ba574fd46a01ff5a41855a97c710ca.jpg",
"1d10802f1b74e660117f36bd6dd0aa26.jpg",
"e705fb66f767a1b914200ca8d3cae700.jpg",
"3d5d8828331e13d3decc94021a64e5ca.jpg"
]
}
]
}
Here what happening means gallery is coming an array , for me don't want array i need first image only, please check my expected results, update the answer
Updated expected results
{
"status": "Success",
"Images": [
{
"gallery_id": "2",
"title": "Annual Day 2017",
"description": "",
"galleryImagesCount": 4,
"gallery": [
{
"galleryimage": "1.jpg"
},
{
"galleryimage": "2.jpg"
}
]
},
{
"gallery_id": "3",
"title": "Sports Day",
"description": "",
"galleryImagesCount": 4,
"gallery": [
{
"galleryimage": "1.jpg"
},
{
"galleryimage": "2.jpg"
}
]
}
]
}
Instead of [galleryImages] => ["1.jpg","2.jpg","3.jpg"], use for loop to iterate through galleryImages.
Create an associative array with key =>value pair like [galleryImages] => ["galleryimage1" => "1.jpg", "galleryimage2" => "2.jpg", "galleryimage3" => "3.jpg"].
While json_decode you will get intended output.
My changes and explanations are in the code block:
Code: (Demo)
// assumed that previous line was something like $response=json_decode($json);
$response=[
(object)[
'gallery_id'=>2,
'title'=>'Annual Day 2017',
'description'=>'',
'galleryImages'=>["1.jpg","2.jpg","3.jpg","4.jpg"],
'reg_on'=>'2017-05-17 01:55:12',
'created_by'=>'rajeshdash123#gmail.com',
'school_id'=>2,
'status'=>0
],
(object)[
'gallery_id'=>3,
'title'=>'Sports Day',
'description'=>'',
'galleryImages'=>["1.jpg","2.jpg","3.jpg"],
'reg_on'=>'2017-05-17 01:55:36',
'created_by'=>'rajeshdash123#gmail.com',
'school_id'=>2,
'status'=>0
]
];
foreach ($response as $value){ // removed $key=> because it was unnecessary
$img['gallery_id'] = $value->gallery_id;
$img['title'] = $value->title;
$img['description'] = $value->description;
$img['galleryImagesCount'] = count($value->galleryImages); // removed json_decode()
$img['gallery'] = $value->galleryImages[0]; // removed json_decode and added [0] to access first
$images[]=$img; // swapped push() call with identical function-less "push"
}
if(isset($images)){ // added this condition to ensure there was something to return
$return=array('status'=>"Success",'Images'=>$images);
//var_export($return);
echo json_encode($return);
}else{
// enter some sort of error message / default behavior
}
Output:
{"status":"Success","Images":[{"gallery_id":2,"title":"Annual Day 2017","description":"","galleryImagesCount":4,"gallery":"1.jpg"},{"gallery_id":3,"title":"Sports Day","description":"","galleryImagesCount":3,"gallery":"1.jpg"}]}

How do we sum individual array elements in MongoDB aggregation query?

Document :
{
"version": "1.0.0",
"actor": {
"objectType": "Agent",
"name": "Test user",
"account": {
"homePage": "http://testing.com/",
"name": "67"
}
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/completed",
"display": {
"en-US": "completed"
}
},
"object": {
"objectType": "Activity",
"id": "http://localhost/action?id=cji",
"definition": {
"type": "http://adlnet.gov/expapi/activities/lesson",
"name": {
"en-US": "ps3"
},
"description": {
"en-US": "ps3"
}
}
},
"timestamp": "2016-10-25T11:21:25.917Z",
"context": {
"extensions": {
"http://localhost/eventinfo": {
"sessionId": "1477393533327",
"starttm": "1477394351210",
"eventtm": "1477394485917",
"course": "cji"
}
},
"contextActivities": {
"parent": [
{
"objectType": "Activity",
"id": "http://localhost/id=cji"
}
]
}
},
"result": {
"duration": "PT2M14.71S",
"score": {
"raw": 6,
"max": 21
}
},
"authority": {
"objectType": "Agent",
"name": "New Client",
"mbox": "mailto:hello#lhd.net"
},
"stored": "2016-10-25T11:20:29.666700+00:00",
"id": "c7039783-371f-4f59-a665-65a9d09a2b7f"
}
We've got this PHP + MongoDB aggregation query:
$condition = array(
array(
'$match' => array(
'client_id' => $CFG->mongo_clientid,
'statement.actor.account.name' => array('$in'=> array('67','192','213')),
'statement.verb.id' => 'http://adlnet.gov/expapi/verbs/completed',
'statement.object.id' => 'http://localhost/action?id=cji'
)),
array(
'$group' => array(
'_id' => '$statement.actor.account.name' ,
//'totalpoints' =>array( '$sum' => array('$last' => '$statement.result.score.raw'))
'laststatement' => array('$last' => '$statement.result.score.raw'),
//'sumtest' => array('$add' => ['$laststatement'])
)
)
);
$cursor = $collection->aggregate($condition);
echo "";
print_r($cursor);
echo "";
which returns this result:
Array
(
[result] => Array
(
[0] => Array
(
[_id] => 192
[laststatement] => MongoInt64 Object
(
[value] => 4
)
)
[1] => Array
(
[_id] => 67
[laststatement] => MongoInt64 Object
(
[value] => 6
)
)
)
[ok] => 1
)
How do we sum [laststatement].[value] of these individual array elements in MongoDB aggregation query?
[laststatement] => MongoInt64 Object
(
[value] => values goes here
)
Also, how do we use $last and $sum together in MongoDB aggregation query?
In my result there are 2 raw scores(last statement) for 2 different id (192,67). I want to sum this scores like 4 + 6 = 10 for all multiple id's but want only the last scores from the last statement. I am unable to use $last and $sum on the line. Please check
Looks like all you want is a single group. So the grouping id should be null. You may want to add a sort if you care for what last record should be. Not tested.
array(
'$group' => array(
'_id' => null ,
'totalpoints' => array( '$sum' => '$statement.result.score.raw')
'laststatement' => array('$last' => '$statement.result.score.raw')
)
)
Here is the mongo shell version.
aggregate([
{
$match :{
"actor.account.name":{$in:["67","192","213"]},
"verb.id":{$eq:"http://adlnet.gov/expapi/verbs/completed"},
"object.id":{$eq:"http://localhost/action?id=cji"}
}
},
{
$group: {
"_id": null,
"totalpoints" : {$sum:"$result.score.raw"},
"laststatement" :{$last:"$result.score.raw"}
}
}
])
Output:
{ "_id" : null, "totalpoints" : 10, "laststatement" : 4 }
Update Changed to include the sum for the last statement from each group. The first grouping is by actor name and returns the last statement from each group. The second grouping sums all the last statement.
aggregate([{
$match: {
"actor.account.name": {
$in: ["67", "192", "213"]
},
"verb.id": {
$eq: "http://adlnet.gov/expapi/verbs/completed"
},
"object.id": {
$eq: "http://localhost/action?id=cji"
}
}
}, {
$group: {
"_id": "$actor.account.name",
"laststatement": {
$last: "$result.score.raw"
}
}
}, {
$group: {
"_id": null,
"totalpoints": {
$sum: "$laststatement"
},
}
}])

Categories