2

I'm trying to parse JSON into an array that is formatted like the following:

{
    "company": [
        [
            {
                "id": 1,
                "name": "Test Company1"
            },
           {
                "id": 2,
                "name": "Test Company2"
            }
        ]
    ]
}

I'm using Newtonsoft JObjects to do this. I have the following code so far, which gets me to the "company" object:

JObject joResponse = JObject.Parse(json);
JArray arr = (JArray)joResponse["company"];

But there is only one value in the array, it's one single value with the all of the JSON nodes in it:

    [
        {
            "id": 1,
            "name": "Test Company1"
        },
       {
            "id": 2,
            "name": "Test Company2"
        }
    ]

So essentially I need to get to that 2nd level, but the 2nd level inside of "company" isn't named so I'm not sure how to access it.

4
  • Just take it by index - JArray arr = (JArray)joResponse["company"][0] Commented Jul 30, 2021 at 23:09
  • company, for unknown reasons, contains a nested array, you need arr[0][0]["name"], arr[0][1]["id"] etc. -- Are you sure this JSON is correct? Commented Jul 30, 2021 at 23:12
  • @Fabjan this will return the array value from the company Commented Jul 30, 2021 at 23:12
  • @Fabjan JArray arr = (JArray)joResponse["company"][0] did the trick, thank you! The JSON comes from an API that we do not own, so I'm not sure why they created it with a nested array so that was I was trying to work around. There should be only ever one "company" array in the nest so using [0] should work perfect. Commented Aug 2, 2021 at 22:42

2 Answers 2

4

You can use something like this:

JToken arr = joResponse["company"]?.Children().First()[1];

Or:

JToken arr = joResponse["company"]?[0]?[1];
Sign up to request clarification or add additional context in comments.

4 Comments

Why using .Children and First when we could just use indexer instead: joResponse["company"][0] ?
@Fabjan As I understood, he wants to have the entry with id 2. This Code returns this entry. With joResponse["company"][0], it will return the whole array, not the 2nd entry from the array.
So joResponse["company"][0][1] would be enough. Don't forget that methods as .First() are upcasting JArray to IEnumerable then call GetEnumerator and Next this adds unnecessary overhead.
@Fabjan is correct in that I was mainly just trying to select all the records in the "Company" array so I could loop through them, but the trouble I was having was that company was an array of an array - That's what I meant by "2nd level" - sorry for the confusion there. joResponse["company"][0] did the trick and your answer includes that also, just selecting only one of the records.
0

The easiest way to do this is to create classes to hold each object type. This is made more complex by the fact that company is actually an array of arrays, for some reason.

class Root
{
    public List<List<Company>> companies { get; set; }
}

class Company
{
    public int id { get; set; }
    public string name { get; set; }
}

Then you simply deserialize into the root object

var result = JsonConvert.DeserializeObject<Root>(json);

var companies = result.companies.SelectMany(c => c).ToList();

2 Comments

This solution worked as well for me, and you are correct in the piece that was complex was because company being an array of arrays for some unknown reason in the formatting. I assume classes and lists are better practices than Jarray's arrays in this case?
Yes, JArray and JObject are for when the JSON structure is entirely unknown, here you know the structure so you should create classes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.