Find highest value entry in sub array using JSON & PHP - 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
)
)

Related

PHP delete json element

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));

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)));

Convert PHP array to specific JSON data

I have trying to generate specific json for Rubrics which require this below format only .
Why I need this ?
https://surveyjs.io/Examples/Library?id=questiontype-matrix-rubric&platform=jQuery&theme=bootstrap#content-js
For surveyJS it i am creating cells json using PHP
PHP output
Array
(
[Attendance] => Array
(
[0] => Array
(
[OUTSTANDING] => A
)
[1] => Array
(
[Satisfactory] => B
)
[2] => Array
(
[Needs Improvement] => C
)
[3] => Array
(
[Unacceptable] => D
)
)
[Punctuality] => Array
(
[0] => Array
(
[OUTSTANDING] => A
)
[1] => Array
(
[Satisfactory] => B
)
[2] => Array
(
[Needs Improvement] => C
)
[3] => Array
(
[Unacceptable] => D
)
)
)
Output I have been trying to achieve and required
{
"Attendance": {
"OUTSTANDING": "A",
"Satisfactory": "B",
"Needs Improvement": "C",
"Unacceptable": "D"
},
"Punctuality": {
"OUTSTANDING": "A",
"Satisfactory": "B",
"Needs Improvement": "C",
"Unacceptable": "D"
}
}
This is what I have tried so far :-
$finalArr = [];
$columns = [];
$rows = [];
$cells = [];
$rubics = json_decode($model->rubric_json);
$points = json_decode($model->points_json);
$rubicsCols = json_decode($model->rubric_json);
if (!empty($rubicsCols[0])) {
$columns = array_filter($rubicsCols[0], 'strlen');
}
if (!empty($points[0])) {
$points = array_filter($points[0], 'strlen');
}
unset($rubics[0]);
if (!empty($rubics)) {
foreach ($rubics as $key => $data) {
$rows[] = [
'value' => $data[0],
'text' => $data[0]
];
}
}
if (!empty($rows)) {
foreach ($rows as $rowKey => $row) {
foreach ($columns as $key => $column) {
$cells[$row['text']][] =[
$column =>$rubics[$rowKey + 1][$key]
] ;
}
}
}
echo "<pre>";
print_r(json_encode($cells,JSON_PRETTY_PRINT));exit;
after json_encode($cells,JSON_PRETTY_PRINT) output is :-
{
"Attendance": [
{
"OUTSTANDING": "Attends all of class.Never arrives late, leaves early, or is in and out of the class while it is in progress."
},
{
"Satisfactory": "Attends most of class.Rarely arrives late, leaves early, or is in and out of the class while it is in progress."
},
{
"Needs Improvement": "Sometimes absent.Sometimes arrives late, leaves early, or is in and out of the class while it is in progress."
},
{
"Unacceptable": "Often absent.Often arrives late, leaves early, or is in and out of the class while it is in progress."
}
],
"Punctuality": [
{
"OUTSTANDING": "Always ready to start when class starts at the beginning of the day and when class resumes after breaks."
},
{
"Satisfactory": "Usually ready to start when class starts at the beginning of the day and when class resumes after breaks."
},
{
"Needs Improvement": "Rarely ready to start when class starts at the beginning of the day and when class resumes after breaks."
},
{
"Unacceptable": "Almost never ready to start when class starts at the beginning of the day and when class resumes after breaks"
}
]
}
You need to flatten each sub-array. Given that structure this should work:
foreach($array as $key => $val) {
$array[$key] = array_merge(...$val);
}
If you have an old PHP version then:
$array[$key] = call_user_func_array('array_merge', $val);
According to json.org specification an associative array will be converted to an object and flat one will be an array, so you need something like:
<?php
$arr = [
'Attendance' => [
'OUTSTANDING' => 'A',
'Satisfactory' => 'B',
'Needs Improvement' => 'C',
'Unacceptable' => 'D'
],
'Punctuality' => [
'OUTSTANDING' => 'A',
'Satisfactory' => 'B',
'Needs Improvement' => 'C',
'Unacceptable' => 'D'
]
];
echo '<pre>';
echo json_encode($arr, JSON_PRETTY_PRINT);

How to search an index by value in two dimensional array in php

I have a function to get description of courier , all records fetched about courier and are stored in $couriers . $courier is two dimensional array since it containing all rows of table couriers .
[
{
"id":"1",
"name":"DTDC",
"description":"Automatically inserted by application ",
"bloked":"false"
},
{
"id":"2",
"name":"Ecomm",
"description":"Nothing",
"bloked":"false"
},
{
"id":"3",
"name":"MarginPrice",
"description":"Local only",
"bloked":"false"
}
]
Now , i have to fetch decription of courier whose id is given . For
this purpose , i must know the index of the records .. I tried it
using array_search but "hard time" . So , i ask for help to give idea
to know the index of that records in array
function getCourierDescriptionById($id)
{ global $couriers;
if($couriers==null)
{
loadCourier($id);
}
$index=array_search($id,$couriers);// Here is the problem
return isset($couriers[$index]['description'])?
$couriers[$index]['description']:null;
}
Try this way easy to use
$j = '[
{
"id":"1",
"name":"DTDC",
"description":"Automatically inserted by application ",
"bloked":"false"
},
{
"id":"2",
"name":"Ecomm",
"description":"Nothing",
"bloked":"false"
},
{
"id":"3",
"name":"MarginPrice",
"description":"Local only",
"bloked":"false"
}
]';
$arr = json_decode($j,true);
$courier =array();
foreach($arr as $sample){
$courier[$sample['id']] = $sample;
}
//make sure your courier variable has id which you want to find "Its easy to search"
function getCourierDescriptionById($id)
{ global $courier;
return isset($courier[$id])? $courier[$id]:null;
}
print_r(getCourierDescriptionById(3));//function call which want to find
Your $courier variable has change for Easy to find, Which is contain array like that:
Array
(
[1] => Array
(
[id] => 1
[name] => DTDC
[description] => Automatically inserted by application
[bloked] => false
)
[2] => Array
(
[id] => 2
[name] => Ecomm
[description] => Nothing
[bloked] => false
)
[3] => Array
(
[id] => 3
[name] => MarginPrice
[description] => Local only
[bloked] => false
)
)
You $courier variable is not an array , it is a json string , so dcode it first which turns it to in php array.
$couriers = json_decode($couriers,true);
Now your function , can be defined as below , by using array_map
function getCourierDescriptionById($id)
{ global $couriers;
$args=func_num_args();
if($couriers==null)
{
loadCourier($id);
}
$index=array_search($id,array_map("getAllCourierId",$couriers));
return isset($couriers[$index]['description'])?
$couriers[$index]['description']:null;
}
Now the function who is bounded with array_map as below
function getAllCourierId($arr)
{
return $arr['id'];
}
Use this
$jsonArray = '[
{
"id":"1",
"name":"DTDC",
"description":"Automatically inserted by application ",
"bloked":"false"
},
{
"id":"2",
"name":"Ecomm",
"description":"Nothing",
"bloked":"false"
},
{
"id":"3",
"name":"MarginPrice",
"description":"Local only",
"bloked":"false"
}
]';
$arrData = json_decode($jsonArray,true);
print_r(searchForId('3',$arrData,'id'));
function searchForId($id, $array,$field) {
foreach ($array as $key => $val) {
if ($val[$field] === $id) {
return $val['description'];
}
}
return null;
}

Taking a string of period separated properties and converting it to a json object in php

I'm fairly sure I'm missing something blindingly obvious here but here it goes.
I am working on updating a search function in an application which was running a loop and doing a very large number of sql queries to get object / table relations to one large query that returns everything. However the only way I could think to return relations was period separated, what I am now wanting to do is take the flat array of keys and values and convert it into an associative array to then be jsonified with json_encode.
For example what I have is this...
array(
"ID"=>10,
"CompanyName"=>"Some Company",
"CompanyStatusID"=>2,
"CompanyStatus.Status"=>"Active",
"addressID"=>134,
"address.postcode"=>"XXX XXXX",
"address.street"=>"Some Street"
);
And what I want to turn it into is this...
array(
"ID"=>10,
"CompanyName"=>"Some Company",
"CompanyStatusID"=>2,
"CompanyStatus"=>array(
"Status"=>"Active"
),
"addressID"=>134,
"address"=>array(
"postcode"=>"XXX XXXX",
"street"=>"Some Street"
)
);
Now I'm sure this should be a fairly simple recursive loop but for the life of me this morning I can't figure it out.
Any help is greatly appreciated.
Regards
Graham.
Your function was part way there mike, though it had the problem that the top level value kept getting reset on each pass of the array so only the last period separated property made it in.
Please see updated version.
function parse_array($src) {
$dst = array();
foreach($src as $key => $val) {
$parts = explode(".", $key);
if(count($parts) > 1) {
$index = &$dst;
$i = 0;
$count = count($parts)-1;
foreach(array_slice($parts,0) as $part) {
if($i == $count) {
$index[$part] = $val;
} else {
if(!isset($index[$part])){
$index[$part] = array();
}
}
$index = &$index[$part];
$i++;
}
} else {
$dst[$parts[0]] = $val;
}
}
return $dst;
}
I am sure there is something more elegant, but quick and dirty:
$arr = array(
"ID"=>10,
"CompanyName"=>"Some Company",
"CompanyStatusID"=>2,
"CompanyStatus.Status"=>"Active",
"addressID"=>134,
"address.postcode"=>"XXX XXXX",
"address.street"=>"Some Street"
);
$narr = array();
foreach($arr as $key=>$val)
{
if (preg_match("~\.~", $key))
{
$parts = split("\.", $key);
$narr [$parts[0]][$parts[1]] = $val;
}
else $narr [$key] = $val;
}
$arr = array(
"ID" => 10,
"CompanyName" => "Some Company",
"CompanyStatusID" => 2,
"CompanyStatus.Status" => "Active",
"addressID" => 134,
"address.postcode" => "XXX XXXX",
"address.street" => "Some Street",
"1.2.3.4.5" => "Some nested value"
);
function parse_array ($src) {
$dst = array();
foreach($src as $key => $val) {
$parts = explode(".", $key);
$dst[$parts[0]] = $val;
if(count($parts) > 1) {
$index = &$dst[$parts[0]];
foreach(array_slice($parts, 1) as $part) {
$index = array($part => $val);
$index = &$index[$part];
}
}
}
return $dst;
}
print_r(parse_array($arr));
Outputs:
Array
(
[ID] => 10
[CompanyName] => Some Company
[CompanyStatusID] => 2
[CompanyStatus] => Array
(
[Status] => Active
)
[addressID] => 134
[address] => Array
(
[street] => Some Street
)
[1] => Array
(
[2] => Array
(
[3] => Array
(
[4] => Array
(
[5] => Some nested value
)
)
)
)
)

Categories