How to iterate through pure JSON Array like the following, in C# Newtonsoft?
[
78293270,
847744,
32816430
]
or,
["aa", "bb", "cc"]
All the existing answers that I found on SO are in KeyValuePair format, not this pure JSON Array format. Thx.
JArray array = JsonConvert.DeserializeObject<JArray>(json);
foreach(JObject item in array)
{
// now what?
}
Parse the string using static Parse method of JArray. This method returns a JArray from a string that contains JSON. Please read it about here.
var jArray = JArray.Parse(arrStr);
foreach (var obj in jArray)
{
Console.WriteLine(obj);
}
A simple program for your inputs which you can run to validate at dotnetfiddle.
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
var arrStr = "[78293270, 847744, 32816430]";
var jArray = JArray.Parse(arrStr);
foreach (var obj in jArray)
{
Console.WriteLine(obj);
}
var aStr = "[\"aa\", \"bb\", \"cc\"]";
var jArray1 = JArray.Parse(aStr);
foreach (var obj in jArray1)
{
Console.WriteLine(obj);
}
}
}
The output of above code is
78293270
847744
32816430
aa
bb
cc
Dotnet Fiddle program
Do you mean "how to get values from iterated JObject?
foreach(var item in array) // var is JToken, can be cast to JObject
{
int number = item.Value<int>();
Console.WriteLine(number);
}
Related
I'd like to iterate through a C# dictionary storing nested JSON to retrieve and pass the dictionary key name to a string, in the form of "key1:key1-1:key1-1-1".
After that, a new dictionary is created to use the specially arranged string as its keys.
Finally, desiredDictionary["key:key:key"] = originalDictionary["key"]["key"]["key"].
Please make the answer specific, my apology that I'm new to C# IEnumerable class and JSON.
I've stored the JSON data into a dictionary, the sample JSON is given below.
using System.Web.Script.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
......
string jsonText = File.ReadAllText(myJsonPath);
var jss = new JavaScriptSerializer();
//this is the dictionary storing JSON
var dictJSON = jss.Deserialize<Dictionary<string, dynamic>>(jsonText);
//this is the dictionary with keys of specially arranged string
var desiredDict = new Dictionary<string, string>();
......
......
//Here is a sample JSON
{
"One": "Hey",
"Two": {
"Two": "HeyHey"
}
"Three": {
"Three": {
"Three": "HeyHeyHey"
}
}
}
I need help with the process for dictionary key name retrieval, string completion, and new dictionary value passing.
According to the given JSON, desiredDict["Three:Three:Three"] = dictJSON["Three"]["Three"]["Three"] = "HeyHeyHey",
The solution is expected to apply on any similar JSON.
You can use a recursive method to take a JObject and produce a flattened dictionary from it like so:
private static IDictionary<string, string> FlattenJObjectToDictionary(JObject obj)
{
// obtain a key/value enumerable and convert it to a dictionary
return NestedJObjectToFlatEnumerable(obj, null).ToDictionary(kv => kv.Key, kv => kv.Value);
}
private static IEnumerable<KeyValuePair<string, string>> NestedJObjectToFlatEnumerable(JObject data, string path = null)
{
// path will be null or a value like Three:Three: (where Three:Three is the parent chain)
// go through each property in the json object
foreach (var kv in data.Properties())
{
// if the value is another jobject, we'll recursively call this method
if (kv.Value is JObject)
{
var childDict = (JObject)kv.Value;
// build the child path based on the root path and the property name
string childPath = path != null ? string.Format("{0}{1}:", path, kv.Name) : string.Format("{0}:", kv.Name);
// get each result from our recursive call and return it to the caller
foreach (var resultVal in NestedJObjectToFlatEnumerable(childDict, childPath))
{
yield return resultVal;
}
}
else if (kv.Value is JArray)
{
throw new NotImplementedException("Encountered unexpected JArray");
}
else
{
// this kind of assumes that all values will be convertible to string, so you might need to add handling for other value types
yield return new KeyValuePair<string, string>(string.Format("{0}{1}", path, kv.Name), Convert.ToString(kv.Value));
}
}
}
Usage:
var json = "{\"One\":\"Hey\",\"Two\":{\"Two\":\"HeyHey\" },\"Three\":{\"Three\":{\"Three\":\"HeyHeyHey\"}}}";
var jObj = JsonConvert.DeserializeObject<JObject>(json);
var flattened = FlattenJObjectToDictionary(jObj);
It takes advantage of yield return to return the results of the recursive call as a single IEnumerable<KeyValuePair<string, string>> and then returns that as a flat dictionary.
Caveats:
Arrays in JSON will throw an exception (see else if (kv.Value is JArray))
The else part for handling the actual values assumes that all values are convertible to string using Convert.ToString(kv.Value). If this is not the case, you will have to code for extra scenarios.
Try it online
My JSON is a very long one and i am fetching only one section "parent_crumbs" from the long JSON
...................,
"parent_crumbs":["Platforms","New platform"],
"promise_by":"2016-08-01",
....
The code I used to fetch value of "parent_crumbs" is
JObject lp_p = JObject.Parse(response_json);
string val= lp_p["parent_crumbs"].ToString();
This returns the following value
"[\r\n \"Platforms\",\"New platform\"\r\n]"
Now I have to do a comparison with the first value from the array as the string is available in a Dictionary as key value and if available return ID
Packages = new Dictionary<string, int>();
Packages.Add("Platforms", 10212);
Packages.Add("New platform", 10202);
Packages.Add("Unknown platform", 10203);
int category=
if(Packages.ContainsKey(val))
{
Packages.TryGetValue(val, out category);
}
So with current code I can't do the comparison straight away due to presence of [\r\n etc.
How to get the value as a string Array without special chars like [\r\n .
Making Model Classes for the JSON for deserialization is not preferred way for me. Since creating class is a big job for me as lot of properties are there in JSON and is dynamic of nature
We can use the below code
var input = "[\r\n \"Platforms\",\"New platform\"\r\n]";
var array =(JArray) JsonConvert.DeserializeObject(input);
bool isEqual = array[0].Value<string>() == "Platforms";
you could also convert it to array with Linq
using System.Linq;
var tmp = lp_p["parent_crumbs"].Select(x => x.ToString());
foreach (var x in tmp)
{
Console.WriteLine(x.ToString());
}
By using Select, it will help you convert it to array rather than to string
You can use DeserializeAnonymousType method for that:
var myType = new
{
parent_crumbs = new []{ "" },
promise_by = default(DateTime)
};
var result = JsonConvert.DeserializeAnonymousType(json, myType);
int category = 0;
string key = result.parent_crumbs[0];
if(Packages.ContainsKey(key))
{
Packages.TryGetValue(key, out category);
}
References: DotNetFiddle Example, DeserializeAnonymousType
I need to cast JArray which I received from browser to list of MyType object. The problem is that I don't want to use .ToObject<> extension because object sended from browser can have missing or extra values and I cannot change deserializer. I wrote my own parser to receive data from single JObject. Usage:
foreach (var _object in _jarray)
{
using (var tp = new TokenParser(_object))
{
MyType test = new MyType()
{
id = tp.ConvertToInt("token_key")
};
}
}
What I want to do is something like this
_jarray.ForEach(_object => {
using (var tp = new TokenParser(_object))
{
MyType test = new MyType()
{
id = tp.ConvertToInt("token_key")
};
}
});
I don't want to cast elements like:
_jarray.Select(x =>
(int)["token_key"]
);
I tried to wrote this extension based on LINQ equivalent of foreach for IEnumerable<T> but it seems that Action requires T as parameter type. I don't need this because JArray is an array of JObject.
Is this possible to achieve?
I have some JSON that looks like this
[
{
"MobileSiteContent": {
"Culture": "en_au",
"Key": [
"NameOfKey1"
]
}
},
{
"PageContent": {
"Culture": "en_au",
"Page": [
"about-us/"
]
}
}
]
I parse this as a JArray:
var array = JArray.Parse(json);
Then, I loop over the array:
foreach (var content in array)
{
}
content is a JToken
How can I retrieve the "name" or "key" of each item?
For example, "MobileSiteContent" or "PageContent"
JToken is the base class for JObject, JArray, JProperty, JValue, etc. You can use the Children<T>() method to get a filtered list of a JToken's children that are of a certain type, for example JObject. Each JObject has a collection of JProperty objects, which can be accessed via the Properties() method. For each JProperty, you can get its Name. (Of course you can also get the Value if desired, which is another JToken.)
Putting it all together we have:
JArray array = JArray.Parse(json);
foreach (JObject content in array.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
Console.WriteLine(prop.Name);
}
}
Output:
MobileSiteContent
PageContent
JObject obj = JObject.Parse(json);
var attributes = obj["parent"]["child"]...["your desired element"];
foreach (JProperty attributeProperty in attributes)
{
var attribute = attributes[attributeProperty.Name];
var my_data = attribute["your desired element"];
}
The default iterator for the JObject is as a dictionary iterating over key/value pairs.
JObject obj = JObject.Parse(response);
foreach (var pair in obj) {
Console.WriteLine (pair.Key);
}
Using Linq we can write something like:
JArray array = JArray.Parse(json);
foreach (JObject content in array.Children<JObject>())
{
List<string> keys = content.Properties().Select(p => p.Name).ToList();
}
If the JToken key name is unknown, and you only need the key's Value regardless of name, simply use the JToken.Values() method.
The below sample assumes the JToken value is a primitive type - first value found is extracted.
Solution can be extended to support Array values.
JToken fooToken = sourceData.
int someNum = fooToken .Values<int?>().First() ?? 0;
int someString = fooToken .Values<string>().First();
The simplest way is to look at the path of each item in the JSON object.
For Each token As JToken In json
Dim key= token.Path.Split(".").Last
Next
I know you can serialize JSON to Dictionary and object[], but the problem is that it requires you to constantly cast things all over the place:
using System.Web.Script.Serialization;
var json = new JavaScriptSerializer { }.DeserializeObject(#"{array:['item1','item2']}") as Dictionary<string, object>;
var strings = new List<string> { };
if (json != null)
{
var array = json["array"] as object[];
if (array != null)
{
foreach (var item in array.Select(i=>i as string))
{
if (!string.IsNullOrWhiteSpace(item))
{
strings.Add(item);
}
}
}
}
return strings.ToArray();
I would much rather do something more like:
try
{
var json = new JavaScriptSerializer { }.DeserializeDynamic(#"{array:['item1','item2']}") as Dictionary<string, dynamic>;
var strings = new List<string>{};
foreach (var item in json["array"])
strings.Add(item as string);
return strings.ToArray();
}
catch { return null; }
I have run into problems with object[] and number types, I'm never sure if it's going to be an int, a float, a decimal, or a double etc. I can't sanitize my json data so it reliably is only a double...
Are there any JSON Serializers for .Net 4.0 that output Dictionary and dynamic[]? That just seams like a more natural choice for working with json then Dictionary and object[]...
JSON.NET should handle your needs (with the Json.NET Dynamic Extensions).
Dictionary<string, object> and Dictionary<string, dynamic> are the same types as far runtime is concerned.
For example this works:
var dynDic =new Dictionary<string,object>{ {"test", 1}}
as Dictionary<string,dynamic>;
int value = dynDic["test"];
So if your first works:
var json = new JavaScriptSerializer { }
.DeserializeObject(#"{array:['item1','item2']}")
as Dictionary<string, object>;
then so should:
var json = new JavaScriptSerializer { }
.DeserializeDynamic(#"{array:['item1','item2']}")
as Dictionary<string, dynamic>;
But then :
foreach (var item in json["array"])
strings.Add(item as string);
doesn't use dynamic invocation so it compiles that same whether the item var was object or dynamic so if you are having problems my guess is it's in the use of dynamic.
Same rule applies to object[] and dynamic[], they are the same type, you can freely cast between them, when you cast you are just telling the compiler how to use the objects from that array.
dynamic[] dynArr = new object[]{1};
So the answer is that anything that will deserialize to Dictionary<string,object> or object[] can be used as Dictionary<string,dynamic> or dynamic[]