How to get values from nested JSON data? - php

Here's my JSON code:
{
"query": {
"count": 2,
"created": "2013-04-03T09:47:03Z",
"lang": "en-US",
"results": {
"yctCategories": {
"yctCategory": {
"score": "0.504762",
"content": "Computing"
}
},
"entities": {
"entity": [
{
"score": "0.902",
"text": {
"end": "19",
"endchar": "19",
"start": "0",
"startchar": "0",
"content": "Computer programming"
},
"wiki_url": "http://en.wikipedia.com/wiki/Computer_programming"
},
{
"score": "0.575",
"text": {
"end": "51",
"endchar": "51",
"start": "41",
"startchar": "41",
"content": "programming"
}
}
]
}
}
}
}
and below is my PHP code
$json_o = json_decode($json,true);
echo "Json result:</br>";
echo $json; // json
echo "</br></br>";
echo "Value result:</br>";
$result = array();
//$entity = $json_o['query']['results']['entities']['entity'];
foreach ($json_o['query']['results']['entities']['entity'] as $theentity)
foreach ($theentity['text'] as $thetext){
$result[] = $thetext['content'];
}
print_r($result);
My expectation is to get the value of content in entity, which is "Computer programming" and "programming".
I already searching around, but still have found the solution yet.
The result of my PHP code is:
Array ( [0] => 1 [1] => 1 [2] => 0 [3] => 0 [4] => C [5] => 5 [6] => 5 [7] => 4 [8] => 4 [9] => p )

Use this loop
foreach ($json_o['query']['results']['entities']['entity'] as $theentity)
{
$result[] = $theentity['text']['content'];
}
http://codepad.viper-7.com/tFxh1w
Output Array ( [0] => Computer programming [1] => programming )

Change your foreach to:
$result = array();
foreach ($json_o['query']['results']['entities']['entity'] as $theentity) {
$result[] = $theentity['text']['content'];
}
print_r($result);
$theentity['text'] is an array of keys => value. You can just access key content instead of looping through all of the entries.
Another way you could do it (though it is a poor choice) is:
foreach($theentity['text'] as $key => $value) {
if( 'content' === $key ) {
$result[] = $value;
}
}
I provide this second example to demonstrate why the original code did not work.
Update
To access other properties like the yctCategories just do something similar
$categories = array();
foreach ($json_o['query']['results']['yctCategories'] as $yctCategory) {
$categories[] = $yctCategory['content'];
}
print_r($categories);

remove the second foreach and replace it with $result[] = $theentity['text']['content'];
using something like http://jsonlint.com/ might make it easier for you to see how the json is structured. alternatively just var_dump (or print_r) the output of your json_decode.

Use simple code:
$array = $json_o['query']['results']['entities']['entity'];
foreach($array as $v){
echo $v['text']['content'];
}

Related

Get all max values from array of objects in php

I have this array of objects i'm getting from query in mysql, i need th
[
{
"id": "11",
"from_userid": "1996",
"contest_id": "29",
"to_userid": "8",
"vote_date": "2020-10-06 01:40:04",
"count_votes": "1"
},
{
"id": "1",
"from_userid": "82",
"contest_id": "29",
"to_userid": "94",
"vote_date": "2020-09-03 07:06:36",
"count_votes": "1"
},
{
"id": "2",
"from_userid": "82",
"contest_id": "29",
"to_userid": "98",
"vote_date": "2020-09-03 07:06:36",
"count_votes": "0"
}
]
I need the object which has highest 'count_votes ' for eg- id-11 and 1 have similar count votes. So the function should return those 2 objects.
The function i am using returns only one object. I need both of the objects whichever maybe but the highest(count_votes) objects.
Expected Output-
[
{
"id": "11",
"from_userid": "1996",
"contest_id": "29",
"to_userid": "8",
"vote_date": "2020-10-06 01:40:04",
"count_votes": "1"
},
{
"id": "1",
"from_userid": "82",
"contest_id": "29",
"to_userid": "94",
"vote_date": "2020-09-03 07:06:36",
"count_votes": "1"
}
]
Function used-
function max_attribute_in_array($array, $prop) {
return max(array_map(function($o) use($prop) {
return $o;
},
$array));
}
And tried this also-
function get_highest($arr) {
$max = $arr[0]; // set the highest object to the first one in the array
foreach($arr as $obj) { // loop through every object in the array
$num = $obj['count_votes']; // get the number from the current object
if($num > $max['count_votes']) { // If the number of the current object is greater than the maxs number:
$max = $obj; // set the max to the current object
}
}
return $max; // Loop is complete, so we have found our max and can return the max object
}
You can use array_column to extract all the count_votes values into an array, which you can then take the max of:
$max = max(array_column($arr, 'count_votes'));
You can then array_filter your array based on the count_votes value being equal to $max:
$out = array_filter($arr, function ($o) use ($max) {
return $o['count_votes'] == $max;
});
Output:
Array
(
[0] => Array
(
[id] => 11
[from_userid] => 1996
[contest_id] => 29
[to_userid] => 8
[vote_date] => 2020-10-06 01:40:04
[count_votes] => 1
)
[1] => Array
(
[id] => 1
[from_userid] => 82
[contest_id] => 29
[to_userid] => 94
[vote_date] => 2020-09-03 07:06:36
[count_votes] => 1
)
)
Demo on 3v4l.org
NOTE max works with single level arrays, so all your objects are converted to int's internally.
As #Nick has pointed out your get_highest can be done via PHP functions:
function get_highest($array, $prop) {
return max(array_column($array, $prop));
}
So all you have to do is filter your array by this get_highest:
$max = get_highest($myArray, 'count_votes');
$maxes = array_filter($myArray, fn($obj) => $obj['count_votes'] === $max);
function get_heighest($arr){
$newArray = array();
$voteCount = 0;
foreach($arr as $obj){
if($obj['count_votes'] >= $voteCount){
array_push($newArray, $obj)
$voteCount = $obj['count_votes'];
}else{
$i = 0;
foreach($newArray as $object){
if($object['count_votes'] < $voteCount){
unset($newArray[$i]);
}
$i++;
}
}
}
return $newArray;
}

PHP array returning only 1 item

I have this part of my code which should return modifier options as an array as shown by the json response below but its only returning 1 item.
{
"id": "Add-sugar",
"external_data": "External data for sugar choice",
"title": {
"translations": {
"en_us": "Add sugar"
}
},
"quantity_info": {
"quantity": {
"max_permitted": 2
},
"overrides": []
},
"modifier_options": [
{
"id": "Sugar",
"type": "ITEM"
}
]
},
{
"id": "Add-milk",
"external_data": "External data for milk choice",
"title": {
"translations": {
"en_us": "Add milk"
}
},
"quantity_info": {
"quantity": {
"max_permitted": 1
},
"overrides": []
},
"modifier_options": [
{
"id": "Milk",
"type": "ITEM"
}
]
}
],
Here is my code below. I want it to return an array of modifier options but I'm only getting array with only one modifier option. May you assist me.
if($option->field_active[$language][0]['value'] <> 0 &&
in_array($uber->field_zone[$language][0]['target_id'], array_column($option->field_zones[$language], 'target_id')) &&
in_array("uber_eats", array_column($option->field_viewable[$language], 'value'))){
$optionInd['id'] = $option->id;
$optionInd['external_data'] = $option->id;
$optionInd['title']['translations']['en'] = ucwords(strtolower($option->name));
$optionInd['price_info']['price'] = (int)$option->field_pricelevel4[$language][0]['value'];
if(isset($option->field_default[$language][0]['value'])){
$optionInd['selected_by_default'] = $option->field_default[$language][0]['value'];
}
if (!in_array($optionInd['id'], array_column($groupInd['modifier_options'], 'id'))){
$groupInd['modifier_options'][] = $optionInd;
}
} //end if option Active
}```
if (!in_array($optionInd['id'], array_column($groupInd['modifier_options'], 'id'))){
$groupInd['modifier_options'][] = array(
"id"=> $optionInd['id'],
"type"=> "ITEM");```
$modifier[] = $groupInd;
$menu = array(
'modifier_groups' => $modifier,
);
perhaps this can help? ($result below is modifier_options array)
$data=json_decode( '{"data":[{"id":"Add-sugar","external_data":"External data for sugar choice","title":{"translations":{"en_us":"Add sugar"}},"quantity_info":{"quantity":{"max_permitted":2},"overrides":[]},"modifier_options":[{"id":"Sugar","type":"ITEM"}]},{"id":"Add-milk","external_data":"External data for milk choice","title":{"translations":{"en_us":"Add milk"}},"quantity_info":{"quantity":{"max_permitted":1},"overrides":[]},"modifier_options":[{"id":"Milk","type":"ITEM"}]}]}',true); # define $data as associative array
$result=[];
foreach ($data['data'] as $a){
array_push($result, $a['modifier_options']);
}
print_r($result);
Output:
Array
(
[0] => Array
(
[0] => Array
(
[id] => Sugar
[type] => ITEM
)
)
[1] => Array
(
[0] => Array
(
[id] => Milk
[type] => ITEM
)
)
)

Merge multi-dimensional arrays and sum column values which share a common value in another column

I have 3 arrays for storing posts,comments, and likes.
These are the JSON strings:
//comments JSON (stores user and comment points)
$comments='[
{
"user": "5",
"points": "12"
},
{
"user": "2",
"points": "1"
},
{
"user": "3",
"points": "1"
}
]';
//likes(stores user and likes point)
$likes='[
{
"user": "1",
"points": 7
},
{
"user": "4",
"points": 4
},
{
"user": "3",
"points": 1
}
]';
//posts (stores user and post points)
$posts='[
{
"user": "1",
"points": "6"
},
{
"user": "3",
"points": "2"
},
{
"user": "2",
"points": "1"
}
]';
I convert these JSONs into arrays like this:
$comment_array = json_decode($comments,TRUE);
$like_array = json_decode($likes,TRUE);
$post_array = json_decode($posts,TRUE);
//echo '<pre>';
//print_r($comment_array);
//print_r($like_array);
//print_r($post_array);
//echo '</pre>';
Now, I'm trying to sum these points and save the result in a new array. It's not mandatory that a user should have entries in all the three arrays. It depends on whether a user has made a comment, post or like.
function mergeArrays($filenames, $titles, $descriptions) {
$result = array();
foreach ( $filenames as $key=>$name ) {
$result[] = array( 'filename' => $name, 'title' => $titles[$key], 'descriptions' => $descriptions[ $key ] );
}
return $result;
}
The above function can merge all the three arrays.
$merged= mergeArrays($comment_array, $like_array, $post_array);
echo '<pre>';
print_r($merged);
echo '</pre>';
However, each array after merging is stored as an index element.
How can I get a result something like this:
$result='[
{
"user": "1",
"points": "13"
},
{
"user": "2",
"points": "2"
},
{
"user": "3",
"points": "4"
},
{
"user": "4",
"points": "4"
},
{
"user": "5",
"points": "12"
}
]';
Considering your three arrays, this code will get you an array with: points, votes and diferent users.
Edit: Adding additional array and printing it to get the output desired by question.
$points = 0;
$uniqueUsers = array();
$votes = 0;
$users = 0;
$result = array();
//Comments
if (!empty($comment_array)) {
foreach ($comment_array as $item) {
if (!in_array($item['user'], $uniqueUsers)) {
array_push($uniqueUsers, $item['user']);
$result[$item['user']] = 0;
}
$votes ++;
$result[$item['user']] += $item['points'];
}
}
// Likes
if (!empty($like_array)) {
foreach ($like_array as $item) {
if (!in_array($item['user'], $uniqueUsers)) {
array_push($uniqueUsers, $item['user']);
$result[$item['user']] = 0;
}
$votes ++;
$result[$item['user']] += $item['points'];
}
}
// Posts
if (!empty($post_array)) {
foreach ($post_array as $item) {
if (!in_array($item['user'], $uniqueUsers)) {
array_push($uniqueUsers, $item['user']);
$result[$item['user']] = 0;
}
$votes ++;
$result[$item['user']] += $item['points'];
}
}
foreach ($result as $idUser=>$points) {
echo "\n";
echo "\n" . 'User: ' . $idUser;
echo "\n" . 'Points: ' . $points;
}
$results = array('users'=> count($uniqueUsers), 'votes'=>$votes, 'points'=> $points);
//print_r($results);
The solution using array_column, array_walk_recursive and array_values functions:
...
$comments = array_column($comment_array, 'points', 'user');
$likes = array_column($like_array, 'points', 'user');
$posts = array_column($post_array, 'points', 'user');
$list = [$comments, $likes, $posts];
$result = [];
array_walk_recursive($list, function($v, $k) use(&$result){
if (key_exists($k, $result)){
$result[$k]['points'] += $v;
} else {
$result[$k] = ['user' => $k, 'points' => $v];
}
});
$result = array_values($result);
print_r($result);
The output:
Array
(
[0] => Array
(
[user] => 5
[points] => 12
)
[1] => Array
(
[user] => 2
[points] => 2
)
[2] => Array
(
[user] => 3
[points] => 4
)
[3] => Array
(
[user] => 1
[points] => 13
)
[4] => Array
(
[user] => 4
[points] => 4
)
)
Do the following to get one array with summed points:
$collections = array(
'comments' => json_decode($comments,TRUE),
'likes' => json_decode($likes,TRUE);,
'posts' => json_decode($posts,TRUE),
);
$newArray = array();
foreach ($collections as $collection) {
foreach ($collection as $user) {
$newArray[$user->user] += $user->points;
}
}
There are two important points to make if you want to learn the "best" way to handle these types of operations.
Don't use iterated in_array() calls when isset() can be used instead. This is because isset() is much more efficient than in_array().
Use temporary keys to identify duplicate occurrences, then re-index your results when finished -- usually with array_values(), but this time I used array_multisort() to re-order the results AND re-index.
Code: (Demo)
$merged = array_merge(json_decode($comments, true), json_decode($likes, true), json_decode($posts, true));
$result = [];
foreach ($merged as $entry) {
if (!isset($result[$entry['user']])) {
$result[$entry['user']] = $entry;
} else {
$result[$entry['user']]['points'] += $entry['points'];
}
}
array_multisort(array_column($result, 'user'), $result);
// usort($result, function($a, $b) { return $a['user'] <=> $b['user']; });
// array_multisort() will outperform `usort()` in this case.
echo json_encode($result);
Output:
[{"user":"1","points":13},{"user":"2","points":2},{"user":"3","points":4},{"user":"4","points":4},{"user":"5","points":"12"}]
Decode each array and merge them together into a multi-dimensional array.
Iterate each subarray and determine if it is the first occurrence of the user. If so, retain the entire subarray. If not, only increase the points tally within that subarray.
When the loop is finished, sort by user ascending.
This is clean, direct, and readable.

how to get a value of multidimensional array on php

hi im bulding a site with php that use a json api and i need to echo the values of an multidimensional array
"troopsLevels": [
{
"value": 5,
"globalID": 4000000
},
{
"value": 5,
"globalID": 4000001
},
{
"value": 4,
"globalID": 4000002
},
this is a example of my json file what i need is to show the value "value" knowing depending of the globalID
but not sure how to do it
i was thinking something like
$troop_lvl = $data['troopsLevels'];
if($troop_lvl['globalID'] == 4000000){echo $troop_lvl['value']}
but of curse this will not work as i dont specify the item [0]..[2]
but that actually thats what i need to avoid using [0] to select specific array i need to read all and only show the ['value'] when i give the globalid
i really hope yo can understand me english is not my mother language
thanks a lot for you help
You need to use foreach loop
foreach ($troop_lvl as $key=>$value) {
if($value['globalID'] == 4000000) {
echo $value['value'];
}
}
Use foreach
foreach ($troop_lvl as $key=>$value) {
if($value['globalID'] == 4000000) {
echo $troop_lvl['value'];
}
}
See below:
<?php
$arr = array("test" => array("value" => 1, "value2" => 2), "test2" => array("value" => 21, "value2" => 22));
$encode_arr = json_encode($arr);
$decode_arr = json_decode($encode_arr);
//print_r($decode_arr);
foreach ($decode_arr as $key => $value) {
if($value->value2==2)
echo $value->value;
}
?>
The output will be 1.
This should work for you,
$a = '{"troopsLevels": [
{
"value": 5,
"globalID": 4000000
},
{
"value": 5,
"globalID": 4000001
},
{
"value": 4,
"globalID": 4000002
}
]}';
$abc = json_decode($a);
foreach ($abc->troopsLevels as $row) {
if ($row->globalID == 4000000) {
echo $row->value;// prints value as 5 for the current input.
}
}

PHP array to be the same out to JSON format structure

Here's what I want to do in my php array to be exact json format below:
JSON
{
"suggestions": [
{ "value": "Alex - alex#email.com", "data": {"id": 1, "name": Alex } },
{ "value": "John - john#email.com", "data": {"id": 2, "name": John } },
{ "value": "Diaz - diaz#email.com", "data": {"id": 3, "name": Diaz } }
]
}
Query result in my php array:
array(
0 => array('id'=>'1' 'email'=>'alex#email.com', 'name'=>'Alex'),
1 => array('id'=>'2' 'email'=>'john#email.com', 'name'=>'John'),
2 => array('id'=>'3' 'email'=>'diaz#email.com', 'name'=>'Diaz')
);
Do you have any idea how will you make my php array to that JSON format way?
You can simply use json_encode(); function for that.
json_encode($array);
This should help you for your JSON format
foreach($query as $key => $val){
$json[$key]['value'] = $val['name']." - ".$val['email'];
$json[$key]['data']["id"] = $val['id'];
$json[$key]['data']["name"] = $val['name'];
}
echo json_encode($json);
foreach ($your_array as $key => $val) {
foreach ($val as $k => $v) {
if ($v == 'email') {
//get the value of 'email' key in 'value'
$newArr['suggestions']['value'] = current($v);
}
else {
//if value is not email push it in 'data' key
$newArr['suggestions']['data'] = $v;
}
}
}
//lastly encode the required array
echo json_encode($newArr);

Categories