Read integer or doubles from JsonArray in C# - c#

I have to receive a json file from my server and I need to parse it. Until now, I receive all fields as strings:
{"key1":"12", "key2":"23.5",...}
I read it like this:
JsonArray root = JsonValue.Parse(jsonString).GetArray();
for (uint i = 0; i < root.Count; i++)
{
int id = Convert.ToInt32(root.GetObjectAt(i).GetNamedString("id"));
int state = Convert.ToInt32(root.GetObjectAt(i).GetNamedString("state"));
.....
But now, I receive some of the data as integers or doubles and I don't know how to parse it in the way I did until now because there is no method to return an int with a string given.
{"key1":12, "key2":23.5,...}

System.Json does not allow you to see the difference between integers and floating point numbers. You might want to try Json.NET, which does:
var parsed = JObject.Parse("{\"key1\":12, \"key2\":23.5 }");
foreach (JProperty node in parsed.Children())
{
Console.WriteLine("{0}: {1}", node.Name, node.Value.Type);
}
The output:
key1: Integer
key2: Float
Of course, there are other libraries out there that can deal with JSON, but at least Json.NET works with Silverlight and supports your scenario.

Related

Parsing string as int with "Model.x" property in for loop remains in string format

I have a simple form that accepts a number from a radio button selection (1-5) of 11 questions and posts the values into a database as varchar(10) data. I intend to send the user to a result page that lists the sum of these scores through a simple for loop, but when I try parsing the data to integer format, it simply results in zero due to error parsing. Here's an example of my code:
// Q1 - Q11 are the questions in my Db, using Model property
int sum = 0;
int temp = 0;
String question;
for (int i = 11; i >= 1; i--)
{
question = "Model.Q" + i.ToString();
temp = int.Parse(question);
sum += temp;
}
return sum;
What's strange is that if I parse them individually, such as writing:
Int32.TryParse(Model.Q5, out temp);
I am able to parse the data just fine. My console shows that the loop keeps the question variable as "Model.Qx" with quotations, ultimately resulting in 0 for the sum. I have also tried using Int32.TryParse(); for that as well and it resulted in no difference, besides handling the error.
Can a string simply not be parsed if it contains punctuation in concatenation with the i variable, or am I missing something else here? I want to avoid parsing each question individually, as it looks rather ugly in code.
Thanks in advance.
You problem is that you're trying to access a variable by using a string with the same name. This won't work, in the same way that the name gitgecko is not you.
If your model has got a number of properties with similar names, you could write a function to switch between them:
object GetQ(int number)
{
switch(number)
{
case 1: return Model.Q1;
case 2: return Model.Q2;
// etc...
}
}
Or you could change your model to store these variables in an array or list, or whatever is appropriate.
For example, if you've currently got:
class Model
{
string Q1;
string Q2:
// repeated 11 times
You could have:
class Model
{
string[] Q = new string[11];
}
which gives you the ability to do Model.Q[x]

Confusion using SimpleJSON - JSON interpretor

I'm using SimpleJSON which can be found here. <-- Source and documentation.
Here's the JSON that's being output in my PHP script using the json_encode function.
{
"response":3,
"establishments":[
["1","-107.102180","39.410870","0"],
["8","-106.977715","39.377403","7.03707478751404"],
["9","-106.843636","39.484631","14.706647410396497"],
["12","-106.950661","39.230804","14.846070600598637"]
]
}
In the examples on the SimpleJSON page, "establishments" should technically be a nested object, and not a nested array. After going through the code I had assumed that the following would suffice
int id = N["establishments"][0].Value
double long = N["establishments"][1].Value
double lat = N["establishments"][2].Value
Where N is the node containing the Json Information (more info in docs).
However all of these values are returning blank, could anyone point out why? So far arrays have been my only problem with this, and I don't understand the logic behind this enough to figure out what's wrong on my own.
NOTE: As pointed out by #jskidie this is a two dimensional array, I'm having problems returning the full Array (in the 2nd dimension) not the values.
Because you have multi dimensional array. Try:
int id = N["establishments"][0][0].Value
double long = N["establishments"][0][1].Value
double lat = N["establishments"][0][2].Value
What I was looking for was stored in the JSONArray class.
JSONArray array = json["establishments"].AsArray;
for(int i = 0; i < array.Count; i++) {
}
which allows me to iterate over all occurrences.

File Parsing where one column of an array needs to be converted to a different type

Still learning and looking for a little guidance - I've got a CSV file that I'm reading into my program using a method with two foreach loops like so:
int i = 0;
int j = 0;
string File = File.ReadAllText("c:\\employees.txt");
string[,] filesArray = new string[File.ReadLines("c:\\employees.txt").Count(), 4];
foreach (string row in rawFile.Split('\n'))
{
foreach (string col in row.Trim().Split(','))
{
filesArray[i, j] = col;
j++;
}
j = 0;
i++;
}
return filesArray;
All well and good and I can dumbly display the text fine but the format of the CSV file is
Z0003, EmployeeNameHere, 00001
and I want to do some math and other calculations based on the values in filesArray[2, 0] and so on but I'm trying to find what would be best practice for this situation.
I can think of ways that don't seem elegant and honestly it's been a bit of a mess trying to find the exact answer to this question through Google. I don't want to pick up bad habits at such an early stage!
Your problem right now is you have the data (even though getting it is ugly), but it is all in strings. No matter what you do, you will have to convert to a decimal or other numeric format to do math on it.
I would recommend using a library like FileHelpers to read your CSV data into an "employee" class first. This will give you strongly typed objects. See the 'Quick Start Delimited' entry on the left side. your class would look something like this:
[DelimitedRecord(",")]
public class Employee {
// fields in same order as in the file
public string EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int MyNumber { get; set; }
}
Suggestions for current code:
What is rawFile ?? you get the lines using ReadAllLines()
Follow .NET naming guidelines. var file = ... not var File =
Don't use the same name as common .Net classes (e.g. File). Call it fileLines, etc
Don't read the file twice to get the # of lines. use new string[fileLines.Count, 4]
You can use LINQ and calls to split easier if you don't use a [,] multi-dimensional array.
To convert between string and int, you will need int.Parse or int.TryParse
Add error checking to make sure your lines are the correct length, etc
Some sample code:
var data = fileLines.Select(line => line.Split(','))
.Where(arr => arr.Length == 4) // should have 4 fields
.ToArray();
var xxxx = data[0][1]; // should be "EmployeeNameHere"
// this assumes your data is ALL valid
var numbers = data.Select(x => int.Parse(x[2])).ToList();
var sum = numbers.Sum();
// there is no "pretty" way to do TryParse
var numbers = new List<int>();
foreach(var arr in data) {
int temp = 0;
if (int.TryParse(arr[2], out temp)) {
numbers.Add(temp);
}
}

Large Decimal Number Parse

I know this has some answers but not exactly what I'm looking for.
I have an application with a custom scripting language for file formats where numbers can be added, subtracted, etc...
One part will produce decimal,hex conversion and I was able to use the BigInteger class which is nice because I don't have to worry about large values.
For math operations though I am stuck using a Decimal and I would like to know if anyone has any suggestions for something like BigInteger that I can use for Decimal. I have seen BigRational but it doesn't look like it will fit.
Here is the code snippet where it's used. The asdecimal probably looks stupid but it's just decimal parse where zero is returned if invalid.
private string Subtract(StringReader reader, string text)
{
string value = reader.ReadToEnd();
value = Evaluate(value);
var a = text.AsDecimal();
var b = value.AsDecimal();
return (a - b).ToString();
}
To make this more clear. This function can handle any conceivable situation because of BigInteger
private string HexToDec(string value)
{
try
{
var input = this.Evaluate(value);
var number = BigInteger.Parse(input, System.Globalization.NumberStyles.HexNumber);
return number.ToString();
}
catch (Exception)
{
return "INVALID_HEX_NUMBER";
}
}
I would like subtract tot be as flexible. If it's not possible, that is fine.

How can I deserialize integer number to int, not to long?

I'm using Json.NET to deserialize requests on the server-side.
There is something like
public object[] Values
I need to put in values like 30.0, 27, 54.002, and they need to be double's and int's.
Json.NET has a deserialization property called FloatParseHandling, but there is no option like IntParseHandling. So the question is how can I deserialize integers to int?
Your best bet is to deserialize into a typed model where the model expresses that Values is an int / int[] / etc. In the case of something that has to be object / object[] (presumably because the type is not well-known in advance, or it is an array of heterogeneous items), then it is not unreasonable for JSON.NET to default to long, since that will cause the least confusion when there are a mixture of big and small values in the array. Besides which, it has no way of knowing what the value was on the way in (3L (a long), when serialized in JSON, looks identical to 3 (an int)). You could simply post-process Values and look for any that are long and in the int range:
for(int i = 0 ; i < Values.Length ; i++)
{
if(Values[i] is long)
{
long l = (long)Values[i];
if(l >= int.MinValue && l <= int.MaxValue) Values[i] = (int)l;
}
}

Categories