PHP delete json element - php

the json data is
[name] => stdClass Object
(
[first] => Andy
[middle] =>
[last] => James
)
[age] => 18
[lovely] => Array
(
[0] => running
[1] => coding
[2] => -
)
I need to delete [lovely][2] because that's no answer, but I write this code, it's not working...
$keysToRemove = array("N/A", "-", "");
// Recursively iterate through object and remove keys with specified values
function cleanObject($obj) {
foreach ($obj as $key => $value) {
if (is_object($value) || is_array($value)) {
$obj->$key = cleanObject($value);
} else {
if (in_array($value, $GLOBALS['keysToRemove'])) {
unset($obj->$key);
}
}
}
//print_r($obj);
return $obj;
}
the output is
{"name":
{"first":"Andy","last":"James"},"age":18,
"lovely":["running","coding","-"]}
it's error.
the correct output is
{"name":{"first":"Andy","last":"James"},"age":18,
"lovely":["running","coding"]}
how can delete "-"??

As "lovely" key is an Array and not an Object, you can't use Array->Property expression like you do in case of Object. For this purpose, add following block to your code:
$string = '{"name": {"first": "Andy", "middle": "", "last": "James"}, "age": "18", "lovely": ["running", "coding", ""]}';
$json = json_decode($string);
$keysToRemove = array("N/A", "-", "");
function cleanObject ($obj) {
foreach ($obj as $key => $value) {
if (is_object($value) || is_array($value)) {
$obj->$key = cleanObject($value);
} else {
if (in_array($value, $GLOBALS['keysToRemove'])) {
if (is_array($obj)) {
unset($obj[$key]);
} else {
unset($obj->$key);
}
}
}
}
return $obj;
}
var_dump(cleanObject($json));

Related

JSON Delet value

[
{
"1":{
"a":"blablabla",
"b":"...",
"c":"..",
"e":"..."
},
"2":{
"a":"blablabla",
"b":"...",
"c":"..",
"e":"..."
},
"3":{
"a":"blablabla",
"b":"...",
"c":"..",
"e":"..."
}
}
]
desired result :
[
{
"1":{
"a":"blablabla",
"b":"...",
"c":"..",
"e":"..."
},
"3":{
"a":"blablabla",
"b":"...",
"c":"..",
"e":"..."
}
}
]
hi,
I have a JSON that looks like this, I would like to be able to delete data 2 for example ( with a b c e ), anyone to help me?
I tried a lot of things but it always ends up deleting everything.
I found this which seems to show me the right way, but I can't adapt the code.
$data = file_get_contents('teste_data.json');
$json_arr = json_decode($data, true);
$arr_index = array();
foreach ($json_arr as $key => $value) {
if ($value['YOUR KEY'] == SOME VALUE TO COMPARE) {
$arr_index[] = $key;
}
}
foreach ($arr_index as $i) {
unset($json_arr[$i]);
}
$json_arr = array_values($json_arr);
file_put_contents('teste_data.json', json_encode($json_arr));
I want to retrieve the value deleted with a GET, but then I don't know how to delete only this one
You have an array level you are not taking into account
Here is the array:
Array
(
[0] => Array (
[1] => Array (
[a] => blablabla
[b] => ...
[c] => ..
[e] => ...
)
[2] => Array (
[a] => blablabla
[b] => hello
[c] => ..
[e] => ...
)
[3] => Array (
[a] => blablabla
[b] => ...
[c] => ..
[e] => ...
)
)
)
So, see comments to find the changes
$data = file_get_contents('teste_data.json');
$json_arr = json_decode($data, true);
$arr_index = array();
foreach ($json_arr[0] as $key => $value) {
// change ^^^
if ($value['b'] == 'SOME VALUE TO COMPARE') {
$arr_index[] = $key;
}
}
foreach ($arr_index as $i) {
unset($json_arr[0][$i]);
// change ^^^
}
$json_arr = array_values($json_arr);
file_put_contents('teste_data.json', json_encode($json_arr));
Since you changed your desired result, here is the original answer and the modified one:
Remove the key's in the object:
<?php
$delete = ["a", "c"];
$json = json_decode(file_get_contents('teste_data.json'), true);
foreach ($json[0] as $key => $array) {
foreach ($delete as $value) {
if (array_key_exists($value, $array)) {
unset($array[$value]);
}
}
$json[$key] = $array;
}
file_put_contents('teste_data.json', json_encode(array_values($json)));
Remove the keys in the array:
<?php
$delete = [1, 3];
$json = json_decode(file_get_contents('teste_data.json'), true);
foreach ($delete as $value) {
if (array_key_exists($value, $json[0])) {
unset($json[$value]);
}
}
file_put_contents('teste_data.json', json_encode(array_values($json)));

Find highest value entry in sub array using JSON & PHP

I have been playing around with this for a few hours now and have had not much luck.
My current JSON looks like this:
https://pastebin.com/TSmWFA2g
"10-10-2019 12:00AM":[
{
"speed":33,
"latitude":-11.2588112,
"longitude":100.8249533
},
{
"speed":33,
"latitude":-11.2381112,
"longitude":100.82509
},
{
"speed":31,
"latitude":-11.827312,
"longitude":100.8242733
}
],
"10-10-2019 12:01AM":[
{
"speed":29,
"latitude":-11.2902112,
"longitude":100.8202849
},
{
"speed":26,
"latitude":-11.2826432,
"longitude":100.3760333
}
]
What I am attempting to do is for each date find the entry that has the highest "speed" and remove the other entries under that date (or create a new array with the single entry).
EDIT 01:
I have now tried:
function my_sort($a,$b)
{
return $b['speed'] - $a['speed'];
}
usort($finalData,"my_sort");
echo json_encode($finalData);
This sorts the data by speed but the JSON now does not include the date found in the original JSON.
[{"speed":33,"latitude":-11.2588112,"longitude":100.82509},
{"speed":33,"latitude":-11.2588112,"longitude":100.82509},
{"speed":31,"latitude":-11.2588112,"longitude":100.82509},
{"speed":31,"latitude":-11.2588112,"longitude":100.82509},
{"speed":33,"latitude":-11.2588112,"longitude":100.82509},
{"speed":32,"latitude":-11.2588112,"longitude":100.82509},
{"speed":24,"latitude":-11.2588112,"longitude":100.82509},
{"speed":16,"latitude":-11.2588112,"longitude":100.82509},]
<?php
$data = json_decode('{
"10-10-2019 12:00AM":[
{
"speed":33,
"latitude":-11.2588112,
"longitude":100.8249533
},
{
"speed":33,
"latitude":-11.2381112,
"longitude":100.82509
},
{
"speed":31,
"latitude":-11.827312,
"longitude":100.8242733
}
],
"10-10-2019 12:01AM":[
{
"speed":29,
"latitude":-11.2902112,
"longitude":100.8202849
},
{
"speed":26,
"latitude":-11.2826432,
"longitude":100.3760333
}
],
"10-10-2019 12:02AM":[
{
"speed":35,
"latitude":-11.2991112,
"longitude":100.0129199
},
{
"speed":33,
"latitude":-11.9273112,
"longitude":100.8734016
},
{
"speed":32,
"latitude":-11.2533212,
"longitude":100.19229
},
{
"speed":30,
"latitude":-11.2928112,
"longitude":100.2495099
},
{
"speed":24,
"latitude":-11.2228112,
"longitude":100.9266033
}
]
}',true);
$newArray=array();
foreach ($data as $key => $value) {
array_multisort(array_column($value, 'speed'), SORT_DESC, $value);
$newArray[$key]=$value[0];
}
echo "<pre>";
print_r($newArray);
echo "<pre>";
?>
$max = []; //store highest speeds in new array
foreach ($json as $key => $obj) {
$max[$key] = max(array_map(function($o) {
return $o;
}, $obj));
}
Working sample: http://sandbox.onlinephpfunctions.com/code/2f6e1a86775e206650bfe86f7602464c0fce17f0
As you just want the highest for each date, this code just loops round each item and stores the one with the highest speed for the date, if there are multiple ones with the same speed, the first is taken. This saves having to sort the arrays and then chop them up and makes 1 pass through the data...
$output = [];
$input = json_decode($data, true);
foreach ( $input as $date => $dateSection ) {
$max = ["speed" => 0];
foreach ( $dateSection as $item ) {
if ( $item["speed"] > $max["speed"] ) {
$max = $item;
}
}
$output[$date] = $max;
}
print_r($output);
this gives the output...
Array
(
[10-10-2019 12:00AM] => Array
(
[speed] => 33
[latitude] => -11.2588112
[longitude] => 100.8249533
)
[10-10-2019 12:01AM] => Array
(
[speed] => 29
[latitude] => -11.2902112
[longitude] => 100.8202849
)
[10-10-2019 12:02AM] => Array
(
[speed] => 35
[latitude] => -11.2991112
[longitude] => 100.0129199
)
)

check whether key-value present in any object in array (array of object)

I have array of object as
$a = [{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}];
here i want to create new array of abject in which duplicate object will not be there (invoice_id) as new array will be having first object of same invoice_id. i was doing like this.
foreach ($a as $key => $value) {
if(isset($new)) {
foreach ($new as $k => $val) {
if($val->id != $value->id) {
$new[] = $value;
}
}
}else{
$new[] = $value;
}
}
my new array will be like
$new = [{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]
but it is not giving desired output . What should be done ?
Since you tagged this as Laravel question use collections.
Less code (one line!) and performance hit is non-existent.
$a = json_decode('[{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}]');
$result = collect($a)->groupBy('invoice_id');
After OP edited question:
$result = collect($a)->unique('invoice_id')->values()->toArray();
results in:
=> [
{#826
+"id": "20",
+"invoice_id": "123",
},
{#824
+"id": "22",
+"invoice_id": "125",
},
]
or using ->toJson() instead of ->toArray()
"[{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]"
Please try the below code with simple logic,
$temp = $new = array();
$b = json_decode($a, true);
foreach ($b as $key => $val) {
if(!in_array($val['invoice_id'], $temp)) {
$temp[$val['id']] = $val['invoice_id'];
$new[] = array('id' => $val['id'], 'invoice_id' => $val['invoice_id']);
}
}
print_r($new);
I am just creating a temp array to store only the unique invoice_id to compare in a loop.
It gives the below result,
Array
(
[0] => Array
(
[id] => 20
[invoice_id] => 123
)
[1] => Array
(
[id] => 22
[invoice_id] => 125
)
)
$result = [];
foreach ($a as $data) {
$result[$data->id] = $data;
}
var_dump(array_values($results));
Try this
$a = json_decode($a);
$invoiceid = [];
$unique = [];
foreach ($a as $key => $value) {
if(!in_array($value->invoice_id,$invoiceid)) {
$invoiceid[] = $value->invoice_id;
$unique[] = $value;
}
}
echo $a = json_encode($unique);

Array_search in object array

I have this small search function in my page;
$searchWord is the word that I need to look for in my array.
The array looks a bit like this:
stdClass Object (
[ActionScopeId] => 181365
[DateChanged] => 0001-01-01T00:00:00
[DateCreated] => 2013-08-20T13:59:33.053
[Description] => Snelheid test
[MessageCode] => C0000448220
)
stdClass Object (
[ActionScopeId] => 181364
[DateChanged] => 0001-01-01T00:00:00
[DateCreated] => 2013-08-14T10:08:50.707
[Description] => Test
[MessageCode] => C0000448219
)
Now, for example; I want to look for the word 'Test'. When it's found, I want to print the ActionScopeId and DateCreated with it.
This is my code:
$roc = array('relation' => $_SESSION['username']);
$rocresponse = $wcfclient->ReadOpenCalls($roc);
foreach ($rocresponse->ReadOpenCallsResult as $key => $value){
foreach ($value as $key1 => $value1){
if (array_search($searchWord,$value1)){
echo $value1->ActionScopeId;
}
}
}
But, the result I get is always empty. What am I doing wrong?
I fixed it, when trying to search into an object you can use this function:
function in_object($val, $obj){
if($val == ""){
trigger_error("in_object expects parameter 1 must not empty", E_USER_WARNING);
return false;
}
if(!is_object($obj)){
$obj = (object)$obj;
}
foreach($obj as $key => $value){
if(!is_object($value) && !is_array($value)){
if($value == $val){
return true;
}
}else{
return in_object($val, $value);
}
}
return false;
}
And then look for it in this way:
if (in_object($searchWord,$value)){
I fixed this by using this function:
function in_object($val, $obj){
if($val == ""){
trigger_error("in_object expects parameter 1 must not empty", E_USER_WARNING);
return false;
}
if(!is_object($obj)){
$obj = (object)$obj;
}
foreach($obj as $key => $value){
if(!is_object($value) && !is_array($value)){
if($value == $val){
return true;
}
}else{
return in_object($val, $value);
}
}
return false;
And then look for it in this way:
if (in_object($searchWord,$value)){}

Is there something like keypath in an associative array in PHP?

I want to dissect an array like this:
[
"ID",
"UUID",
"pushNotifications.sent",
"campaigns.boundDate",
"campaigns.endDate",
"campaigns.pushMessages.sentDate",
"pushNotifications.tapped"
]
To a format like this:
{
"ID" : 1,
"UUID" : 1,
"pushNotifications" :
{
"sent" : 1,
"tapped" : 1
},
"campaigns" :
{
"boundDate" : 1,
"endDate" : 1,
"pushMessages" :
{
"endDate" : 1
}
}
}
It would be great if I could just set a value on an associative array in a keypath-like manner:
//To achieve this:
$dissected['campaigns']['pushMessages']['sentDate'] = 1;
//By something like this:
$keypath = 'campaigns.pushMessages.sentDate';
$dissected{$keypath} = 1;
How to do this in PHP?
You can use :
$array = [
"ID",
"UUID",
"pushNotifications.sent",
"campaigns.boundDate",
"campaigns.endDate",
"campaigns.pushMessages.sentDate",
"pushNotifications.tapped"
];
// Build Data
$data = array();
foreach($array as $v) {
setValue($data, $v, 1);
}
// Get Value
echo getValue($data, "campaigns.pushMessages.sentDate"); // output 1
Function Used
function setValue(array &$data, $path, $value) {
$temp = &$data;
foreach(explode(".", $path) as $key) {
$temp = &$temp[$key];
}
$temp = $value;
}
function getValue($data, $path) {
$temp = $data;
foreach(explode(".", $path) as $ndx) {
$temp = isset($temp[$ndx]) ? $temp[$ndx] : null;
}
return $temp;
}
function keyset(&$arr, $keypath, $value = NULL)
{
$keys = explode('.', $keypath);
$current = &$arr;
while(count($keys))
{
$key = array_shift($keys);
if(!isset($current[$key]) && count($keys))
{
$current[$key] = array();
}
if(count($keys))
{
$current = &$current[$key];
}
}
$current[$key] = $value;
}
function keyget($arr, $keypath)
{
$keys = explode('.', $keypath);
$current = $arr;
foreach($keys as $key)
{
if(!isset($current[$key]))
{
return NULL;
}
$current = $current[$key];
}
return $current;
}
//Testing code:
$r = array();
header('content-type: text/plain; charset-utf8');
keyset($r, 'this.is.path', 39);
echo keyget($r, 'this.is.path');
var_dump($r);
It's a little rough, I can't guarantee it functions 100%.
Edit: At first you'd be tempted to try to use variable variables, but I've tried that in the past and it doesn't work, so you have to use functions to do it. This works with some limited tests. (And I just added a minor edit to remove an unnecessary array assignment.)
In the meanwhile, I came up with (another) solution:
private function setValueForKeyPath(&$array, $value, $keyPath)
{
$keys = explode(".", $keyPath, 2);
$firstKey = $keys[0];
$remainingKeys = (count($keys) == 2) ? $keys[1] : null;
$isLeaf = ($remainingKeys == null);
if ($isLeaf)
$array[$firstKey] = $value;
else
$this->setValueForKeyPath($array[$firstKey], $value, $remainingKeys);
}
Sorry for the "long" namings, I came from the Objective-C world. :)
So calling this on each keyPath, it actually gives me the output:
fields
Array
(
[0] => ID
[1] => UUID
[2] => pushNotifications.sent
[3] => campaigns.boundDate
[4] => campaigns.endDate
[5] => campaigns.pushMessages.endDate
[6] => pushNotifications.tapped
)
dissectedFields
Array
(
[ID] => 1
[UUID] => 1
[pushNotifications] => Array
(
[sent] => 1
[tapped] => 1
)
[campaigns] => Array
(
[boundDate] => 1
[endDate] => 1
[pushMessages] => Array
(
[endDate] => 1
)
)
)

Categories