Search into multidimensional array and change value of one key - php

I have one json request which contain multiple array:
{
"user_type": "2",
"user_id": "57",
"client_detail": [
{
"server_user_id": "1",
........
........
"is_active": "1",
"client_local_id": "11"
},
{
"server_user_id": "2",
........
........
"is_active": "1",
"client_local_id": "12"
}
],
}
Using above request I change data into database. then return data from DB. but i have to pass client_local_id into response.
so suppose i got 3 result from DB then i have to return client_local_id(this field is not stored in DB, there is no need for that) with them. so i pass default client_local_id 0.
exa:
"client_detail": [
{
"server_user_id": "1",
........
........
"is_active": "1",
"client_local_id": 0
},
{
"server_user_id": "2",
........
........
"is_active": "1",
"client_local_id": 0
},
{
"server_user_id": "3",
........
........
"is_active": "1",
"client_local_id": 0
},
]
then using below code i change value of client_local_id.
$response = array('client_detail' => $dbvalue);
/* Change Client Local ID */
if(sizeof($client_detail_data)>0)
{
foreach($client_detail_data as $key=>$resclient_data) // loop of request
{
foreach($response['client_detail'] as $key1=>$res_client) //loop of response
{
//if id is match then change value
if($res_client['server_user_id']==$resclient_data['server_user_id'])
{
$response['client_detail'][$key1]['client_local_id'] = $resclient_data['client_local_id'];
}
}
}
}
But i think there is easy method, to do that. I have a multiple array in request so i don't want to use too much foreach loop. so how to solve it in proper way?
Thanks in advance.

First of all let’s map server_user_ids to client_user_ids:
$s2c = array();
foreach($resclient_data as $item) {
$s2c[$item['server_user_id']] = $item['client_user_id'];
}
Now we can use array_map directly on $response:
$response['client_detail'] = array_map(function($elem) use($s2c) {
$elem['client_local_id'] = $s2c[$elem['server_local_id']];
return $elem;
}, $response['client_detail']);
I diidn’t test the code, but hopefully the idea is clear.

Related

Refactor the JSON object in Laravel

Here's my JSON:
[
{
"ID": 1,
"SOURCEID": 1,
"TIMESTAMP": "2020-04-05 07:05:29",
"VALUE": "30"
},
{
"ID": 4,
"SOURCEID": 2,
"TIMESTAMP": "2020-04-05 07:05:17",
"VALUE": "40"
},
{
"ID": 3,
"SOURCEID": 1,
"TIMESTAMP": "2020-04-06 12:04:59",
"VALUE": "35"
},
{
"ID": 5,
"SOURCEID": 1,
"TIMESTAMP": "2020-06-17 12:01:32",
"VALUE": "1"
},
{
"ID": 6,
"SOURCEID": 2,
"TIMESTAMP": "2021-06-17 13:55:29",
"VALUE": "2"
}
]
I need to refactor the JSON like
I need JSON to be refactor based on timestamp and source id and JSON is dynamic like a number of source id present in the given JSON there are two ids that is 1 and 2. Below I gave the expected output.
I need a Unique time stamp in a separate array-like
[2020-04-05,2020-04-06,2020-06-17,2021-06-17]
{ "sourceid: 1, "data":[30,35,1,0], }, { "sourceid": 2, "data":[40,0,0,2], }
Note: The value fills according to the date. Other it should fill as 0.
I have tried like this :
`$data=json_decode($result);
$timestamp=[];
$dataList=[];
foreach ($data as $value){
$date=\Carbon\Carbon::parse($value->TIMESTAMP)->toDateString();
if(!in_array($date, $timestamp, true)){
array_push($timestamp, $date);
}
if(isset($dataList[$value->SOURCEID])){
array_push($dataList[$value->SOURCEID]['data'],$value->VALUE);
} else{
$dataList[$value->SOURCEID]=[
'SOURCEID'=>$value->SOURCEID,
'data'=>[$value->VALUE]
];
}
}
dump($timestamp);
dump($dataList);`
But it produce like
{ "sourceid: 1, "data":[30,35,1], }, { "sourceid": 2, "data":[40,2]}
but I need like
{ "sourceid: 1, "data":[30,35,1,0], }, { "sourceid": 2, "data":[40,0,0,2] }
You need to find the unique timestamps and source ids and then use that to develop your new array. Since you are using laravel, using a collection makes it easier.
I used the transform modifier to modify the TIMESTAMP field so we can "query" it easier via ->where
Please note, I am using the 2nd param true modifier for the json_decode function to get an associative array rather than an object.
$data = json_decode($result, true); // note true
$collection = collect($data);
// transform the timestamp column
$collection->transform(function ($item) {
$item['TIMESTAMP'] = \Carbon\Carbon::parse($item['TIMESTAMP'])->toDateString();
return $item;
});
// get all unique timestamps and source ids
$timestamps = $collection->pluck('TIMESTAMP')->unique();
$sourceIds = $collection->pluck('SOURCEID')->unique();
$dataList = [];
foreach ($sourceIds as $sourceId) {
$items = $collection->where('SOURCEID', $sourceId);
$dataList[$sourceId]['sourceid'] = $sourceId;
foreach ($timestamps as $timestamp) {
$occurrence = $items->where('TIMESTAMP', $timestamp)->first();
if ($occurrence) {
$dataList[$sourceId]['data'][] = $occurrence['VALUE'];
} else {
$dataList[$sourceId]['data'][] = 0;
}
}
}
dd($dataList);
Note you might want to cast $occurrence['VALUE']; to int via (int) $occurrence['VALUE'];
For more information on collections click here.
Output:

Looping through a json file to find a particular value in PHP

My json file look likes
myjson.json
[
{"name":"category_01","data":
[
{"id":"1","word":"ma","given_value":"1"},
{"id":"3","word":"me","given_value":"1"},
] }
[
{"name":"category_02","data":
[
{"id":"1","word":"vea","given_value":"1"},
{"id":"3","word":"ve","given_value":"1"},
] }
So what I want here is, check whether a particular value is in this json array using php. Assume that,
myphp.php
$word = 've';
if this value is in the above array, should find is it in category_01 or category_02. and also want to find given_value of matching word.
I just tried in this way,
$data = file_get_contents ("myjson.json");
$json = json_decode($data, true);
foreach($arr as $item) {
$uses = ($item['word']= $word);
}
This doesn't work. How can I fix this, Please help me!
First of all, the JSON you posted is invalid. I think it should look like this:
[
{
"name": "category_01",
"data": [{
"id": "1",
"word": "ma",
"given_value": "1"
},
{
"id": "3",
"word": "me",
"given_value": "1"
}
]
},
{
"name": "category_02",
"data": [{
"id": "1",
"word": "vea",
"given_value": "1"
},
{
"id": "3",
"word": "ve",
"given_value": "1"
}
]
}
]
Try using on online tool like https://jsonlint.com/ to check your JSON. (if you get errors i recommend build the json again from scratch).
I also recommend checking your json before using it:
if ($arr === null && json_last_error() !== JSON_ERROR_NONE) {
die("incorrect json data");
}
To get your value you have to KNOW how your data looks like and then process it:
foreach($arr as $category) {
foreach($category['data'] as $data) {
if(strstr($data['word'], $word))
echo $category['name'].' '.$data['word'].' '.$data['given_value']."\n";
}
}

JSON structure PHP - strange

Im working with Google tag Manager API(v2), and trying to add some new lines to my existing JSON array. I first had some trouble adding data to my JSON object because the data was shown on the last row and not inside the object itself.
Now ive changed my code but the data does not look like its inside the object itself but im a little bit closer now. This is how my JSON object looks like now:
JSON:
{
"Account2": [{
"accountId": "17467*****",
"containerId": "745****",
}, 3, 3, 4, {
"accountId": "17467*****",
"containerId": "751****",
}, 1, 1, 2],
"Account 1": [{
"accountId": "17661*****",
"containerId": "748****",
}, 2, 1, 1],
"GTMdocx": [{
"accountId": "21200*****",
"containerId": "803****",
}, 0, 0, 1],
"Account3": [{
"accountId": "21281*****",
"containerId": "803****",
}, 0, 0, 0]
}
As you can see the object is structured like this:
1) Accountname
2) Inside Accountname we have accountId and containerId
3) at last of one Accountname object we have some numbers(count), the problem is that it looks like this:
What i would want the JSON-object to look like is like this:
{
"Account2": [{
"accountId": "17467*****",
"containerId": "745****",
"tags": "3",
"triggers": "3",
"variables": "4"
}, {
"accountId": "17467*****",
"containerId": "751****",
"tags": "3",
"triggers": "3",
"variables": "4"
}],
"Account 1": [{
"accountId": "17661*****",
"containerId": "748****",
"tags": "2",
"triggers": "1",
"variables": "1"
}],
"GTMdocx": [{
"accountId": "21200*****",
"containerId": "803****",
"tags": "0",
"triggers": "0",
"variables": "1"
}],
"Account3": [{
"accountId": "21281*****",
"containerId": "803****",
"tags": "0",
"triggers": "0",
"variables": "0"
}]
}
You can see the numbers got a key and then value inside the object.
This is my PHP-code:
static public function listAllContainers() {
try { //Because some containers might not have live-version
$containers[] = array();
foreach (self::listAccounts()->account as $accountKey => $account) {
foreach (self::listAccountsContainers($account["path"]) as $account_container) {
$containers[$account['name']][] = $account_container;
$container_version = self::listAccountsContainersVersion($account_container['path']);
$containers[$account['name']][] = count($container_version['tag']);
$containers[$account['name']][] = count($container_version['trigger']);
$containers[$account['name']][] = count($container_version['variable']);
}
}
$filtered_array = (object)array_filter((array)$containers); // Removes empty object
return $filtered_array;
} catch (\Exception $e) {
return $e->getCode();
}
}
Hope you understand my problem. Not so much experience with Arrays/JSON so maybe my explanation is not so good.
Thanks!
UPDATE:
Using $containers[$account['name']]['tag'] = count($container_version['tag']); gives me this JSON: (PS: ive removed some from the json so it wont be long, this makes the json invalid)
{
Account2: {
0: {
accountId: "174675****",
containerId: "745****",
},
1: {
accountId: "174675****59",
containerId: "751****83",
},
tag: 1,
trigger: 1,
variable: 2
},
Account 1: {
0: {
accountId: "1766***525",
containerId: "748***53",
},
tag: 2,
trigger: 1,
variable: 1
},
Now each "Account" can have multiple "containers"(accountId,containerId), using this method does not store the data inside the object itself.
If you have an array, you can add a key:value pair to it with the following syntax:
$array['key'] = 'value';
//array('key' : 'value')
If you don't specify a key, it will just add the value:
$array[] = 'value';
//array('value')
The last part is what you are doing now, but you add it to your $containers[...] array. What you want to do is add the values first to your $account_container array, and then add that array to your $containers[...] array. Put this in the inner foreach:
$container_version = self::listAccountsContainersVersion($account_container['path']);
//Add values to account_container
$account_container['tag'] = count($container_version['tag']);
$account_container['trigger'] = count($container_version['trigger']);
$account_container['variable'] = count($container_version['variable']);
// Add account_container to your $containers[..] array
$containers[$account['name']][] = $account_container;
I put together another solution without modifying the original $account_container.
I've added the new data in a new array $account_container_extra and merged that together with $account_container when appending it to the $container array.
Maybe that will work better for you or give you some other ideas.
static public function listAllContainers() {
try { //Because some containers might not have live-version
$containers[] = array();
foreach (self::listAccounts()->account as $accountKey => $account) {
foreach (self::listAccountsContainers($account["path"]) as $account_container) {
$container_version = self::listAccountsContainersVersion($account_container['path']);
$account_container_extra = [
'tag' => count($container_version['tag']),
'trigger' => count($container_version['trigger']),
'variable' => count($container_version['variable'])
];
$containers[$account['name']][] = array_merge($account_container, $account_container_extra);
}
}
$filtered_array = (object)array_filter((array)$containers); // Removes empty object
return $filtered_array;
} catch (\Exception $e) {
return $e->getCode();
}
}

Accessing array inside array

I'm working on my task right now, which accessing specific array when it is called by front end.
My example data is like this
{
"data": [
{
"name": "Jon Snow",
"id": "01-0001",
},
{
"name": "Robert Stark",
"id": "01-0002"
},
{
"name": "Sansa Stark",
"id": "01-002333"
},
{
"name": "Arya Stark",
"id": "01-00012"
},
{
"name": "Bran Stark",
"id": "01-0003"
},
{
"name": "Rickon Stark",
"id": "01-0005"
}
]
}
* In my front end I have this code *
selectedEmployee: any=null;
setActiveEmployee(employee: any) {
this.selectedEmployee = employee;
let myJSON = JSON.stringify(this.selectedEmployee);
this.perEmpLateEarly();
}
Whenever I choose the employee i get the id of that employee.
So in this, if i choose "id": "01-0001" it will return the first array and it will keep the rest, and if I choose "id": "01-0002" it will return the second one and will keep the rest and so on. How can I do that in Php?
Thanks in advance
You will do a GET/POST HTTP request from frontend, which would look something like this in
your_backend_page.php?id=<ID HERE>
Then the "your_backend_page.php" would look like as follows:
$list = { "data": [ { .... }, { ... }] } // this is the array you have
$idFromFrontEnd = $_GET["id"];
foreach ($list["data"] as $item) { // iterate over all items
if ($item["id"] == $idFromFrontEnd) { // check if id matches
echo json_decode($item); // if matches, print this item
}
}
Please note this approach is okay if you have a small number of items. For a larger list, you might want to have a database, where you can use sql to select.

imploding array_keys from Facebook JSON data

Need some help with the sample code provided the facebook. I can't get it to return a series of IDs that I need to run a sql query against.
$friends = '{
"data": [
{
"name": "Paul",
"id": "12000"
},
{
"name": "Bonnie",
"id": "120310"
},
{
"name": "Melissa",
"id": "120944"
},
{
"name": "Simon",
"id": "125930"
},
{
"name": "Anthony",
"id": "120605"
},
{
"name": "David",
"id": "120733"
}
]
}';
$obj = json_decode($friends);
print $obj->{'data'}[0]->{'name'};
I can return the "Paul"
what I want is to return all the id's using implode(array_keys($obj),",")
I am only getting data to return.
What I'd like to do is retrieve all the IDs separated by a comma.
Thanks!
Try implode-ing on the data key with array_map:
function get_id($o) {
return $o->id;
}
implode(array_map('get_id', $obj->data),",")

Categories