Rebuild a json data remove duplicate value in one child node - php

Here is some json data:
[
{"a":"abc","b:":"10"},//"a":"abc"
{"a":"abd","b:":"12"},
{"a":"abc","b:":"14"},//"a":"abc"
{"a":"abe","b:":"15"},
{"a":"abf","b:":"16"},
{"a":"abg","b:":"17"},//"a":"abg"
{"a":"abg","b:":"19"}//"a":"abg"
]
I want remove all the duplicate values in the child node "a" (remain the first appear one).
Output =>
[
{"a":"abc","b:":"10"},//first appear "a":"abc"
{"a":"abd","b:":"12"},
{"a":"abe","b:":"15"},
{"a":"abf","b:":"16"},
{"a":"abg","b:":"17"}//first appear "a":"abg"
]

This is tested and appears to work as you've described:
$json = <<<JSON
[
{"a":"abc","b:":"10"},
{"a":"abd","b:":"12"},
{"a":"abc","b:":"14"},
{"a":"abe","b:":"15"},
{"a":"abf","b:":"16"},
{"a":"abg","b:":"17"},
{"a":"abg","b:":"19"}
]
JSON;
$json_array = json_decode( $json, TRUE );
$new_array = array();
$exists = array();
foreach( $json_array as $element ) {
if( !in_array( $element['a'], $exists )) {
$new_array[] = $element;
$exists[] = $element['a'];
}
}
print json_encode( $new_array );
It outputs [{"a":"abc","b:":"10"},{"a":"abd","b:":"12"},{"a":"abe","b:":"15"},{"a":"abf","b:":"16"},{"a":"abg","b:":"17"}], which I believe matches your desired output.

Related

Need help to debug json response

I am trying to sent response in that form
{"files":[{"webViewLink":""},{"webViewLink":""}]}
But I'm getting response like that
{"files":[{"webViewLink":"""}]}{"files":[{"webViewLink":"""}]}
Here is my PHP code:
<?php
$idtemp = extractfiles($fol_id, $email);
foreach ($idtemp['items'] as $val) {
$id = $val['id'];
$val = array(
"webViewLink" => 'https://drive.google.com/file/d/'.$val['id'].'/view?usp=drivesdk"'
);
$enc = json_encode($val);
$val = '{"files":['.$enc.']}';
echo($val);
Please help me to fix code i need response in that way
{"files":[{"webViewLink":""},{"webViewLink":""}]}
You should no do $val = '{"files":['.$enc.']}';
Use json_encode to make json, don't do it manual
Create an object with desired keys outside the loop
Push anything to the desired array
Convert to json
<?php
$idtemp = extractfiles($fol_id, $email);
$json = (object) [
"files" => []
];
foreach ($idtemp['items'] as $val) {
$json->files[] = (object) [
"webViewLink" => 'https://drive.google.com/file/d/'.$val['id'].'/view?usp=drivesdk"'
];
}
$json = json_encode($json);
echo($json);
If I use some dummy values to create an example, the output is:
{
"files": [
{
"webViewLink": "https://drive.google.com/file/d/1/view?usp=drivesdk\""
},
{
"webViewLink": "https://drive.google.com/file/d/2/view?usp=drivesdk\""
},
{
"webViewLink": "https://drive.google.com/file/d/3/view?usp=drivesdk\""
}
]
}
As you can test in this online demo

How to remove the arrays given in the arrows

$session_activity_category = array();
foreach($search_venue as $venue_b) {
$session_activity_category[] = $this->users_model->search_categories_by_session($venue_b->activity_venue_id);
}
return $this->output
->set_content_type('application/json')
->set_status_header(200)
->set_output(json_encode(array('activity_category'=>$session_activity_category,'activity'=>$session_activity,'activity_session'=>$search_session,'activity_venue'=>$search_venue),JSON_UNESCAPED_SLASHES)
);
I want to remove the arrays given in the arrow lines
Convert the JSON to the array. Then just create a new array with the same key active category (in my example, something):
<?php
$json = '
{"something": [[
{
"blah": "blah"
},
{
"blah": "blah"
}
]]}
';
$array = json_decode($json, true);
$array = [
"something" => $array['something'][0],
];
echo json_encode($array);
Which will output:
{"something":[{"blah":"blah"},{"blah":"blah"}]}
Seems that $this->users_model->search_categories_by_session($venue_b->activity_venue_id) returns array of objects. You should parse this objects to the $session_activity_category array each iteration of search_categories_by_session function call.
$session_activity_category = array();
array_walk($search_venue, function($venue_b) use (&$session_activity_category) {
$categories = $this->users_model->search_categories_by_session($venue_b->activity_venue_id);
foreach ($categories as $category) {
$session_activity_category[] = $category;
}
});

PHP: Check duplicate array key in objects array.

I have an objects array as following
[{"ChannelName":"39-40","Text":"haha"},
{"ChannelName":"39-40","Text":"lala"}
{"ChannelName":"40-41","Text":"bla bla"},
{"ChannelName":"40-41","Text":"kha kha"}]
How can I check duplicate value in ChannelName. What I need to do is when ChannelName exists in array object, I want to replace the ChannelName with new Text. How php check duplicate ChannelName and how to replace of old Text attribute with new Text attribute if ChannelName duplicate?
Try this solution.
$json = <<<JSON
[{"ChannelName":"39-40","Text":"haha"},
{"ChannelName":"39-40","Text":"lala"},
{"ChannelName":"40-41","Text":"bla bla"},
{"ChannelName":"40-41","Text":"kha kha"}]
JSON;
$json_array = json_decode( $json, TRUE );
$new_array = array();
$exists_array = array();
foreach( $json_array as $element ) {
if( !in_array( $element['ChannelName'], $exists_array )) {
$exists_array[] = $element['ChannelName'];
}
else{
$element['ChannelName'] = 'New Value';
}
$new_array[] = $element;
}
print json_encode( $new_array );
Here at New Value section you can change your value as per your requirement.

PhP compare two arrays then write to file

I have inbound return data -> http://php.net/manual/en/function.json-decode.php that is in PhP array format. The file data is the same type. It is just $result from the previous cycle.
$result = api_query("mytrades", array("marketid" => $id));
How do I compare $result array with $file array and then over write FILE with $result data?
In other words, FILE and the data it contains is continuously being updated with $result
compare -> overwrite -> repeat at next execution.
I tried array_diff but it does not like my data types and I cannot find a work around.
Note: .db file is empty at first cycle but becomes populated at first write.
sample code with Array to string conversion error:
<?php
$id = 155;
require_once('phpPlay.php');
$result = api_query("mytrades", array("marketid" => $id));
$lines = file("myDB.db");
$arrayDiffresult = array_diff ( $result, $lines);
var_dump($result);
file_put_contents('myDB.db', print_r($result, true));
?>
var_dump($result);
I think, you looking for some serialization, json_encoding for example.
$result = array(
'return' => array(
array(
"tradeid" =>"74038377",
"tradetype" =>"Sell",
"datetime" =>"2014-11-12 16:05:32",
"tradeprice" =>"0.00675000",
"quantity" =>"22.18670000",
"fee" =>"-0.00007488",
"total" =>"0.14976023",
"initiate_ordertype" =>"Buy",
"order_id" =>"197009493",
),
array(
"tradeid" =>"2",
"tradetype" =>"Sell",
"datetime" =>"2014-11-12 16:05:32",
"tradeprice" =>"0.00675000",
"quantity" =>"22.18670000",
"fee" =>"-0.00007488",
"total" =>"0.14976023",
"initiate_ordertype" =>"Buy",
"order_id" =>"2",
)
)
);
function getdiff($new, $old)
{
//implement right logical diff here
$diff = array();
$old_serialized = array();
foreach ($old as $item) {
$old_serialized[] = json_encode($item);
}
foreach ($new as $item) {
if (in_array(json_encode($item), $old_serialized)) {
continue;
}
$diff[] = $item;
}
return $diff;
}
$old = file_exists('1.db') ? json_decode(file_get_contents('1.db'), 1) : array();
$arrayDiffresult = getdiff($result['return'], $old);
file_put_contents('1.db', json_encode($result['return']));
print_r($arrayDiffresult);

JSONPath Query to get Node-names?

Consider the following piece of JSONPath:
{
"result":[
{
"type":"Residence",
"street":"Piazza di Spagna",
"city":"-4:0"
},
{
"type":"Residence",
"street":"test",
"city":"-4:1"
}
]
}
Is it possible to get a list of all the node-names?
So for example, I want a list like: type, street, city.
Try this
$arr = (json_decode($json)->result[0]);
$array = get_object_vars($arr);
$properties = array_keys($array);
print_r($properties);`
Out put will be
Array
(
[0] => type
[1] => street
[2] => city
)
On PHP >= 5.4 you can obtain your keys with one line of code:
$nodeNames = array_keys( json_decode( $jsonString, True )['result'][0] );
3v4l.org demo
On lower versions (PHP >= 5.2.16), you have to break above code in two lines:
$array = json_decode( $jsonString, True );
$nodeNames = array_keys( $array['result'][0] );
I decode the JSON string with second parameter as True to force result as array, then I call array_keys to obtain the keys of array['result'][0].
Edit: more flexibility
Your example can be processed as above without problems, but what happens if original JSON string has different keys? The above solution will fail if in the first result row there are not all the keys. To obtain all the keys, you can use this code:
$array = json_decode( $jsonString, True );
$nodeNames = array();
foreach( $array['result'] as $row )
{
$nodeNames = array_unique( array_merge( $nodeNames, array_keys( $row ) ) );
}
or, using array_filter, with this code:
$array = json_decode( $jsonString, True );
$nodeNames = array();
array_filter
(
$array['result'],
function( $row )
{
global $nodeNames;
$nodeNames = array_unique( array_merge( $nodeNames, array_keys( $row ) ) );
}
);
By this two equivalent examples, I process each result row, merging the keys in $nodeNames array and using array_unique to delete duplicate keys.
Read more about array_keys()
Read more about array_unique()
Read more about array_filter()
You can use following function to print all keys in an array format
print_r(array_keys($array));
Is the JSON Path definitely going to follow that structure every time? As in Result => Arrays all of which have the same Nodes.
If it does then the following will work:
function getJsonNodes($json) {
$nodes = array();
$decoded = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \InvalidArgumentException('Invalid JSON String passed to getJsonNodes()');
}
$result = $decoded['result'];
if (is_array($result)) {
$nodes = array_keys($result[0]);
}
return $nodes;
}
Usage would be something like:
try {
$nodes = getJsonNodes($json);
} catch (\InvalidArgumentException $e) {
echo $e->getMessage();
}
Means you can catch any Invalid JSON strings that could potentially be passed and mess with the output.
Although as I stated, the above solution will only work if your JSON Path follows the structure to put in your OP.
You can see it in use here: https://ideone.com/dlvdu2
Hope it helps either way.
Is it possible to get a list of all the node-names?
$object = json_decode($json);
$json_array = $object->result;
foreach ($json_array as $key => $value) {
$object_var = get_object_vars($value);
$object_key = array_keys($object_var);
var_dump($object_key);//will get all node_names!
}
Try this
$result[0].type , $result[0].street, $result[0].city
Please check the below code ..Hope will work
<?php
$text[]=array(
result=>array(
"type"=>"Residence",
"street"=>"pizza",
"city"=>"ini"
),
array(
"type"=>"Residence",
"street"=>"pizza",
"city"=>"ini"
)
);
echo json_encode($text);
?>

Categories