Problems with iteration in json object - c#

Im struggling with a json object.
I create the object (RO) with the following code and that Works fine.
string reply = #"" + client.UploadString(url, "POST", LS_json);
RootObject RO = new RootObject();
RO = JsonConvert.DeserializeObject<RootObject>(reply);
RO now contains all the data I have recieved through the json search.
Now, when iterating through the object the foreach iterate one more than (RO) contains:
cnt_V = 0;
foreach (object obj_attributtertype in RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter[cnt_V].type)
{
if (Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].values[0].value);
}
cnt_V++;
}
The thing is that when cnt_V == 4 and "points" to the last entry attributes[cnt_V] then LS_ande is filled as supposed (=="KEY_VALUES").
But then the foreach iterates again (cnt_V == 5), no problem here, but when it is assigned to LS_ande then it dumps (of cource because there is no entry with data for cnt_V == 5).
I dont understand whats wrong. Please be gentle with me and feel free to ask for further information.
Thanks in advance.

While I can't answer this definitively because I don't have the data, this is what I would start with:
//take out the long and lengthy parts to make the rest clearer
//I see there are two things here, intentional?
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
cnt_V = 0;
//Here, you are iterating over something[cnt_V].type, but also change cnt_V in the body.
//Are you sure this is correct?
foreach (object obj_attributtertype in something[cnt_V].type)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}
And looking at it that way, here is my stab in the dark.
Iterate with a for over the Count() of items in something
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
for (var cnt_V = 0; cnt_V < something.Count(); ++cnt_V)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}

Related

C# Question on a changing a string in a function

Is it possible to change a string from another value? Here is my C# code:
if (QuestionNum == 1 && inputAnswer == RightAnswer || inputAnswer == RightAnswerLower)
{
Program.GotQ1Correct = true;
}
I know that in Lua I could of just changed the Program.GotQ1Correct = true; part to
Program.GotQ[QuestionNum]Correct = true;
However was just wondering if this was possible in C#.
Edit
I'm very sorry if I wasn't clear before, so basically in the above lua code it would change GotQ1Correct to GotQ2Correct and so on and was just wondering if there was a similar, simple way to do this in C# without arrays.
seems like you need
// assuming 10 questions
var results = new bool[10];
var correctAnswers = new string[10];
var studAnswers = new string[10];
for (int i; i < 10 ; i++)
{
if(studAnswer[i].ToLower() == correctAnswers[i].ToLower())
results[i] = true;
}
or slightly cleaner
results[i] = studAnswer[i].ToLower() == correctAnswers[i].ToLower();
For more clarity I might do a dictionary.
public IDictionary<int, bool> CheckAnswers(Dictionary<int, string> exam, Dictionary<int, string> answers)
{
var results = new Dictionary<int, bool>();
for(var index = 0; index < exam.Length; index++)
{
if(String.Compare(exam[index], answers[index], true) == 0)
results.Add(exam[index], true);
results.Add(exam[index], false);
}
return results;
}
var correct = CheckAnswers(..., ...).Where(answer => answer.Value == true).Count();
This solution needs refinement, but it is a nice compliment to PM's answer. One of these should at least point you in the proper direction.
The reason I recommended a dictionary, would be you could pass an answer key and exam result. Allowing you to see which are correct and wrong, then use a tally to get the score relatively easy.
So if understand you want to access a property of an object by replacing the name of access property?
You might want to check this post
accessing-object-property-as-string
Copied from the post
System.Reflection.PropertyInfo prop =typeof(YourType).GetProperty("PropertyName");
object value = prop.GetValue(yourInstance);
...
prop.SetValue(yourInstance, "value");

Sorting Dictionary by Value?

I have a dictionary. Everything is working fine but sorting. I have even tried a SortedDictionary.
Here's what I am doing, I have a Dictionary that contains FilePath,FileName alright.
Well I am trying to sort by the Value and then put then put the (Keys) into a list.
Here is my code. (UPDATED: ENTIRE METHOD).
public static void DisplayScriptListNames(){
scriptsList.Clear ();
fileInfo = new DirectoryInfo (Application.dataPath);
if (EclecticGlobalSettings._cSharp && isSharp) {
sharpFiles = fileInfo.GetFiles ("*.cs", SearchOption.AllDirectories).ToList();
} if(EclecticGlobalSettings._usScripts && !isSharp) {
javaFiles = fileInfo.GetFiles ("*.js", SearchOption.AllDirectories).ToList();
}
if (EclecticGlobalSettings._cSharp && isSharp) {
// C#
if (sharpFiles.Count != 0) {
foreach (FileInfo i in sharpFiles){
string line = i.Name.ToString ();
string checkPath = Path.GetDirectoryName (i.FullName);
string assetsPath = checkPath.Substring (i.FullName.IndexOf ("Assets"));
if (!assetsPath.Contains("Editor") && !assetsPath.Contains("Standard Assets")) {
scriptDictionary.Add(i.FullName,i.Name);
scriptsFound += 1;
}
}
}
}
if(EclecticGlobalSettings._usScripts && !isSharp){
//JS
foreach (FileInfo i in javaFiles) {
//string line = i.FullName.ToString ();
string line = i.Name.ToString ();
string checkPath = Path.GetDirectoryName (i.FullName);
string assetsPath = checkPath.Substring (i.FullName.IndexOf ("Assets"));
if (!assetsPath.Contains("Editor") && !assetsPath.Contains("Standard Assets")) {
Debug.Log (i.Name);
scriptDictionary.Add(i.FullName,i.Name);
scriptsFound += 1;
}
}
}
foreach (KeyValuePair<string,string> item in scriptDictionary.OrderBy(key=>key.Value)) {
Debug.Log (item);
scriptsList.Add (item.Key);
}
//scriptsList.AddRange (scriptDictionary.Keys);
//scriptsList.Sort (Path.GetFileName);
//foreach (string ii in scriptsList) {
// Debug.Log (ii);
//
//}
}
Okay, the Debug.Log() is Unity's way of a Console.WriteLine. And it does in fact say it's sorting it. But when I do.
scriptsList.Add (item.Key);
It's unorganized as it was before.
Is there some simple little step I am missing? Because the console does in fact say it's sorted perfectly the way I'd like. But for some reason, the scriptsList.Add(item.key) < For the PATH to the file. Says it isn't sorted.
I would do scriptList.Sort(); But remember, the scriptList is the keys (File Paths). Which is why I've been trying to sort via Values (the file names).
Which again, says it does sort them.
Here's an example of what compiler says
C:/Cat.txt, Cat.txt. C:/Dog.txt, Dog.txt. C:/Wolf.txt,
Wolf.txt.
But when I go to add them to the list.
C:/Wolf.txt. C:/Dog.txt. C:/Cat.txt.
I figured it out guys! I feel like a total dummy.... I had left an old part of code at the top of one of my if statements, and I had, had if(scriptList.Count < 1) { Sort It }. Removed that, and now good to go :)

C# - Fetching a JSON nested Array value

Im trying to find an answer for this but i must be searching for the wrong terms.
Im working on a Windows phone app and am getting data from an API with a nested array value "user.username"
void data_arrived(object sender, DownloadCompleteData e)
{
String data = e.data;
JArray obj = JArray.Parse(data);
for (int i = 0; i < obj.Count; i++)
{
JObject row = JObject.Parse(obj[i].ToString());
var item = new DataList();
item.country = row["title"].ToString() + " (€" + row["price"].ToString() + ") ";
item.code = row["price"].ToString();
item.imageURL = row["urlimage"].ToString();
item.votes = row["votes"].ToString();
item.category = row["category"].ToString();
item.username = row["user.username"].ToString();
list.Items.Add(item);
}
}
Everything else works fine except user.username
How do i use this properly?
Thanks
You can deserialize a valid JSON string to a dynamic object. This will allow you access to underlying object using dot notation. e.g.
dynamic row = JsonConvert.DeserializeObject (obj[i].ToString());
Your final code block inside loop will look like
dynamic row = JsonConvert.DeserializeObject(obj[i].ToString());
Console.WriteLine(row.title.ToString() + " (€" + row.price.ToString() + ") ");
Console.WriteLine(row.price.ToString());
Console.WriteLine(row.urlimage.ToString());
Console.WriteLine(row.votes.ToString());
Console.WriteLine(row.category.ToString());
Console.WriteLine(row.user.username.ToString());
Console.WriteLine();
Console.WriteLine("-----------------------------\n");
There is no "easy" way to achieve this because the . in C# is reserved.
However, you could achieve something pretty close by using a dictionary and collection initializer. It's still somewhat isolated, and doesn't require you to create a custom class.
var obj = new Dictionary<string, object>
{
{ "user.username", "myvalue" }
};
var json = JsonConvert.SerializeObject(obj);
//{"user.username":"myvalue"}

How to quickly cut up and reassemble a C# List?

The setup:
I have a session variable that carries a list of IDs, pipe-delimited. The IDs are related to views in my site, and related to a breadcrumb builder.
Session["breadCrumb"] = "1001|1002|1003|1004";
If I'm on the view that corresponds to 1002, I'd like to cut everything AFTER that id out of the session variable.
I'd thought to use something like:
var curView = "1002";
if (Session["breadCrumb"] != null) {
var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
var viewExists = crumb.Any(c => c.Value == curView);
if (viewExists) {
//remove everything after that item in the array.
}
}
But I'm wide open to methodologies.
You could use TakeWhile to get back only the items from the splitted list that precede the currentView.
var curView = "1002";
if (Session["breadCrumb"] != null)
{
var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
var viewExists = crumb.TakeWhile(c => c != curView).ToList();
viewExists.Add(curView);
string result = string.Join("|",viewExists);
}
While this approach works I think that also the previous answer (now wrongly deleted from Mr. Andrew Whitaker) was correct. Using IndexOf should be faster with less splitting, looping, joining strings. I suggest Mr Whitaker to undelete its answer.
EDIT
This is from the deleted answer from Mr.Whitaker.
I will repost here because I think that its approach is simpler and should give better perfomances, so future readers could see also this option.
var crumb = Session["breadCrumb"].ToString()
int index = crumb.IndexOf(curView);
if (index >= 0)
{
Session["breadCrumb"] = crumb.Substring(0, index + curView.Length);
}
If Andrew decide to undelete its answer I will be glad to remove this part. Just let me know.
You could just store a List<string> in the Session directly. This saves you from having to split/concat the string manually. I know this does not answer the question directly, but I believe it is a superior solution to that.
var curView = "1002";
var crumb = Session["breadCrumb"] as List<string>;
if (crumb != null) {
var viewExists = crumb.Any(c => c.Value == curView);
if (viewExists) {
// remove everything after that item in the array.
}
}
I almost regret this, but frankly I'd just go for a regular expression:
var result = Regex.Replace(input, "(?<=(\\||^)" + current + ")(?=\\||$).*", "");
This does not directly tell you if the current view existed in the input, but even though this is also possible with the regex in this particular instance another, dead simple test exists:
var viewExists = result.Length != current.Length;

quick and simple way to sort this data taken from a tsv and make it distinct as per one of the fields that it contains

I want to know the quickest and simplest way to sort the code shown below. Sorting from newRecord.AppCode would not be suitable as it will change the meaning of the output. So I need to sort every line from string outp. What would be the best way? Also I would like to make every row distinct. I beleive using LINQ would be very quick but I am not that great at it. Help appreciated. So close to getting it done! Note: Data is being pulled from a tsv. Using .net 3.5, visual studio 2008) Will mark answer as soon as I get progress. :)
while ((line = sr.ReadLine()) != null)
{
String[] splitted = line.Split('\t');
appcodes.Add(line);
Records newRecord = new Records();
newRecord.Server = splitted[0];
newRecord.Instance = splitted[1];
newRecord.AppCode = splitted[2];
newRecord.Database = splitted[3];
listrecords.Add(newRecord);
for (int i = 0; i < appcodes.Count(); i++)
{
if (newRecord.AppCode==appcodes[i].ToUpper())
{
String outp = newRecord.AppCode + " " + newRecord.Server + " " + newRecord.Instance + " " + newRecord.Database;
Console.WriteLine(outp);
}
}
}
have lists named Keepers and newkeepers. Was trying to do something like outp.sort() and outp.sort() but it doesnt work in strings. This is how I solved the problem.
Keepers.Add(outp);
Keepers.Sort();
newKeepers = Keepers.Distinct().ToList();
foreach (object o in newKeepers)
{
Console.WriteLine(o);
}
Console.ReadLine();
As you can see, newrecords contain different fields so I wrote a LINQ statement to solve the problem.
var sorted_list = (from r in newrecords
orderby r.AppCode, r.Server, r.Instance, r.Database
select r).Distinct().ToList();
var distinctSortedList = sorted_list.Distinct().ToList();

Categories

Resources