I'm having trouble pulling a piece of data from a JSON array. I believe I've tried every answer from similar posts here but I'm missing something. I've imported the org.JSON library. Here is my JSON text:
{
"symbol":"AAPL",
"earnings":[
{
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
},
{
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
]
I'm trying to read the first instance of "actualEPS", there are a total of four in the array. My code currently looks like this:
String jsonIn = sb.toString();
JSONArray earningsArray = new JSONArray(jsonIn);
double eps = 0;
for(int i = 0; i < earningsArray.length(); i++) {
JSONObject jObject = earningsArray.getJSONObject(i);
eps = jObject.getDouble("actualEPS");
} // end for loop
System.out.println("This is the first instance of EPS: " + eps);
The StringBuilder (sb) in the first line is my JSON and prints out correctly in the console just ahead of this block.
The stack trace shows the error in this line:
JSONArray earningsArray = new JSONArray(jsonIn);
The error I'm getting is
"A JSONArray text must start with '[' at 1 [character 2 line 1]"
I've never used JSON prior to now and am not sure what my error is exactly. I tried shortening the String going into the array to begin with just the array opening bracket but that didn't work either. I feel like I'm missing something simple. Where have I gone wrong?
You need to understand there are two types of datastructure in a JSON.
first is Object which always starts with '{' and ends with '}'
second is Array which always starts with '[' and ends with ']'
JsonArray is nothing but an array of JsonObject means a json array will always look like
"jsonarray":[
{
//json object
},
{
// json object
}
]
hope now you understand how json works
now come to your json
{ // jsonObjectParent Starts
"symbol":"AAPL",
"earnings":[ // jsonArray Starts
{ //jsonObject1 Starts
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
}, // jsonOject1 Ends
{ //jsonObject2
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
] //jsonArray Ends
} //jsonObjectParent Ends
So here if you want to parse this json you have to first parse it in a jsonObject as you seen above
JsonObject jsonObjectParent = new JsonObject(jsonIn);
// here jsonobject contains json array so etract it like this
JsonArray jsonArray = jsonObjectParent.getJsonArray("earnings");
//now you can access the values here
JsonObject jsonObject1 = jsonArray.getJsonObject(0); // here 0 means first jsonObject in array if you want all you can make a loop here
string actualEps = jsonObject1.getDouble("actualEPS");
Hope now you understands the concept of how JSON Works
please let me know is this solution worked
Do this :
JSONObject json = new JSONObject(response);
JSONArray data = json.optJSONArray("earnings");
for (int i = 0; i < data.length(); i++) {
JSONObject jsonObject1 = data.getJSONObject(i);
Double actualEPS = jsonObject1.getDouble("actualEPS");
Double consensusEPS = jsonObject1.getDouble("consensusEPS");
Double estimatedEPS= jsonObject1.getDouble("estimatedEPS");
String announceTime = jsonObject1.getString("announceTime");
int numberOfEstimates = jsonObject1.getInt("numberOfEstimates");
Double EPSSurpriseDollar= jsonObject1.getDouble("EPSSurpriseDollar");
String EPSReportDate= jsonObject1.getString("EPSReportDate");
String fiscalPeriod= jsonObject1.getString("fiscalPeriod");
String fiscalEndDate= jsonObject1.getString("fiscalEndDate");
Double yearAgo= jsonObject1.getDouble("yearAgo");
Double yearAgoChangePercent= jsonObject1.getDouble("yearAgoChangePercent");
Double estimatedChangePercent = jsonObject1.getDouble("estimatedChangePercent");
int symbolId = jsonObject1.getInt("symbolId");
}
#Driver8, the JSON earninsArray is a single JSON object and not an array of JSON objects. Your basic idea here is alright everywhere excpet for just that line. Instead of instantiating a JSON array, instantiate a JSON OBJECT.
Should be something like this:
String jsonIn = sb.toString();
JSONObject earningsObject = new JSONObject(jsonIn);
JSONArray earningsArray = earningsObject.getJSONArray("earnings");
double eps = new double(earningsArray.length());
for (int i = 0; i < earningsArray.length(); i++) {
JSONObject j1 = earningsArray.getJSONObject(i);
eps[i] = j1.getDouble("actualEPS");
}
All the values of actualEPS will be stored as per their order in the array declared to store the EPS values.
Hope this helps.
Related
Here is my code:
var emoji = "⭐";
var query = myContext.Products.Where(x => x.Name.Contains(emoji));
var queryString = query.ToQueryString();
var list = query.ToList();
Query returns all table records. If I replace contains to equal works great, but I have to search something like this:
"this is my emoji ⭐"
This is the SQL query:
DECLARE #__emoji_0 nvarchar(4000) = N'⭐'
SELECT [p].[Id], [p].[Name], [p].[Quantity]
FROM [Products] AS [p]
WHERE (#__emoji_0 LIKE N'') OR (CHARINDEX(#__emoji_0, [p].[Name]) > 0)
Is any way to do this in EF Core or raw SQL?
Your main issue is the fact that emojis and strings are represented differently.
Before you can search the emojis you will need to decide how are you gonna unify them both in search query and db.
First of all emojis are a pair of chars.What does that mean? Here as a quote from the Microsoft docs:
"🐂".Length = 2
s[0] = '�' ('\ud83d')
s[1] = '�' ('\udc02')
These examples show that the value of string.Length, which indicates the number of char instances, doesn't necessarily indicate the number of displayed characters. A single char instance by itself doesn't necessarily represent a character.
The char pairs that map to a single character are called surrogate pairs. To understand how they work, you need to understand Unicode and UTF-16 encoding.
Having this in mind I would go as follows:
Define a method which will convert emojis to a UTF16 string[] which will keep the two surrogate chars representation.
internal static string[] EmojiToUtf16Pair(string emoji)
{
string[] arr = new string[2];
for (int i = 0; i < emoji.Length; i++)
{
arr[i] = emoji[i].ToString();
}
return arr;
}
This could be use when you persist emojis in DB. Depending on how you decide to persist the emojis in DB some modification could be done for that method e.g. to return concatenated string or something like that.
I am not sure when, but for some reason you could use another method to do the reverse operation -> UTF16 to Emoji
internal static string UTF16PairToEmoji(string[] codes)
{
var test = string.Empty;
foreach (var i in codes)
{
test += i;
}
var result = test.ToString();
return result;
}
Here is all the code example:
class Program
{
static void Main()
{
var str = "🚴";
var utf16 = string.Join("",EmojiToUtf16Pair(str));
Console.WriteLine(utf16);
var testEmpoji = UTF16PairToEmoji(EmojiToUtf16Pair(str));
Console.WriteLine(testEmpoji);
}
internal static string[] EmojiToUtf16Pair(string emoji)
{
string[] arr = new string[2];
for (int i = 0; i < emoji.Length; i++)
{
arr[i] = emoji[i].ToString();
}
return arr;
}
internal static string UTF16PairToEmoji(string[] codes)
{
var test = string.Empty;
foreach (var i in codes)
{
test += i;
}
var result = test.ToString();
return result;
}
}
emoji ef-core db-query
You have to use like command
SELECT * FROM emoticon where emoji_utf like '👨🏫';
with EF in .net core
Emoticon emoticon=db_context.Emoticons.Where(a=>EF.Functions.Like(a.EmojiUtf,"%"+item.emojiString+"%" ) ).FirstOrDefault();
Hi I have this JSON as a string as a response for an API call
{
"friends": {
"data": [],
"summary": {
"total_count": 42
}
},
"id": "111111111111111"
}
I want to get friends.data and friends.summary.total_count.
Something like :
for (int i = 0 ; i < friends.summary.total_count ; i++)
{
myAmazingArray.pushback(friends.data[i]);
}
I think that total_count is the number of contents in the array.
I also know that in order to get the "id" I have to do : json['name']
You need to use jsonDecode from dart:convert. Actually you don't even need to use the total_count value at all, if the length in data is the same. You can simply use:
import 'dart:convert';
final Map<String, dynamic> dataMap = jsonDecode(json);
final List<dynamic> friendsData = dataMap['friends']['data'];
for(dynamic friend in friendsData) myAmazingArray.pushback(friend);
I don't know what kind of content is contained in data, so I suggest you to find out the runtime type (e.g. String, Map etc.) and exchange the word 'dynamic' in my code above to improve the code quality.
If you wanted to do it with total_count:
final int total_count = dataMap['friends']['summary']['total_count'];
for(int i=0; i<total_count; i++)
myAmazingArray.pushback(friendsData[i]);
How to save JSON array into SharedPreferences?
I've tried some code like this below, but i got some error :
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type
'Text' is not a subtype of type 'String'
for (var x = 0; x < dynamicwidget.length - 1; x++) {
_listOrder={
"id_product": dataJSON[x]["product_id"],
"order_count": dynamicwidget[x].controller.text,
};
}
String json = jsonEncode(_listOrder);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(categoryname, json);
I would recommend you to use something like this (local storage implementation) which is made for saving and loading JSON.
From the code snippet itself i can't tell you exactly what is causing this exception but basically everywhere a String is beeing expected but you provided an actual Text widget. It could be the categoryname variable. What kind of controller do you get from your dynamicWidget instance? Are you sure controller.text returns a String?
Another note: you are re-assigning _listOrder with every for loop instead of adding information. You have to use an empty array which will be filled with every loop.
Thanks all, for contributing this question.
I've solved this question and makes some change.
_listOrder.clear();
for (var x = 0; x < dynamicwidget.length; x++) {
int jml = int.parse(dynamicwidget[x].controller.text == ""? "0": dynamicwidget[x].controller.text);
if (jml > 0) {
_listOrder.add({
"id_product": dataJSON[x]["product_id"],
"order_count": dynamicwidget[x].controller.text,
});
}
}
if (_listOrder.length > 0) {
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> _collOrder = Map<String, dynamic>();
String sessjson = prefs.getString("orderlist");
if (sessjson != null) {
_collOrder = json.decode(sessjson);
_collOrder.remove(categoryname);
}
_collOrder[categoryname] = _listOrder;
prefs.setString("orderlist", json.encode(_collOrder));
}
I have a Angular utility server and in that I have one method which I am using for searching some values in a JSON as below.
angular.module('myAppModule')
.service('myService', ['$rootScope', function($rootScope)
{
this.myTestJson = '[{"id":1,"somthing":"somthing"},{"id":2,"somthing":"somthing"}]';
this.getJsonObj = function(id)
{
if(id == null || id == undefined || id == "")
return null;
// Units Convert to JSON
var jsonObj = JSON.parse(JSON.stringify(this.myTestJson)); // How can I avoid this doing every time ?
console.log("getJsonObj: jsonObj.length: "+jsonObj.length); //--> Printed invalid number, length of the string
for(var index=0;index < jsonObj.length;index++)
{
if( id == jsonObj[index].id )
return jsonObj[index];
}
return null;
};
}]);
Problem is I get JSON array length as invalid, and because of that I am not able to loop the array.
How can I access this JSON variable which is defined in the same service.
this.myTestJson = '[{"id":1,"somthing":"somthing"},{"id":2,"somthing":"somthing"}]';
So, myTestJson is a String containing a JSON payload.
var jsonObj = JSON.parse(JSON.stringify(this.myTestJson));
And here, you're serializing this JSON string into JSON, only to reparse it right after. Which doesn't make any sense: you'll end up with the exact same string as the original one. Just like, if you transofmr an integer to a String, and then parse that String into an integer, you'll end up with the original integer.
To parse the original JSON and thus transform it to a JavaScript array, all you need is
var array = JSON.parse(this.myTestJson);
But even this is completely unnecessary, since you could just use a JavaScript array from the start, instead of parsing a JSON string:
var array = [
{
id: 1,
somthing:"somthing"
},
{
id: 2,
somthing: "somthing"
}
];
was wondering if someone could show me what I'm doing wrong here.
I have some old AS2 flash code I'm trying to get working.
First I create a few arrays in frame 1 of the main timeline like so-
var typeArr:Array = new Array();
for (var i:Number = 1; i < 5; i++)
{
_root.typeArr[i] = "data goes here";
}
Then I have a movieclip dynamically attached on the main stage that when clicked appends one of the arrays we created by pushing the string 'foo' to it-
stop();
_root.myType=3;//this can be any of our array numbers
this.onPress=function(){
var foo:String="test";
_root.typeArr[_root.myType].push(foo);
trace(_root.typeArr[_root.myType]);
}
Where _root.typeArr[_root.myType] is the array name and number _root.typeArr3, but pushing the data does not work and returns nothing.
However, if I test it directly using-
_root.typeArr[_root.myType]=foo;
It will store the data once (_root.typeArr3=test), so I can't see why it won't push to that array as multiple elements each time like- "test,test,test"
It's driving me crazy.
Thanks! :)
_root.typeArr[_root.myType] is equal to "data goes here" so you are pushing string to a string, which doesn't work.
If you would like to append the new string, you should do something like:
_root.typeArr[_root.myType]+=foo;
and you will get: data goes heretest
If you have different data structure instead of "data goes here" the key may lie in the format of this data.
var typeArr:Array = new Array();
// 'i' must start from 0 because the first element is typeArr[0]
for (var i:Number = 0; i < 5; i++)
{
typeArr[i] = i;
// trace(typeArr[i]); // 0,1,2,3,4
}
// trace(typeArr); // 0,1,2,3,4
myType = 3;
bt.onPress = function()
{
var foo:String = "test";
// push method puts the element at the end of your array
// typeArr.push(foo);
// trace(typeArr); // 0,1,2,3,4,test
// splice method replace the 4e element (index 3) of your array
typeArr.splice(myType, 1, foo);
trace(typeArr); // 0,1,2,test,4
}