1

I am trying to extract the following fields from the JSON feed at the bottom of this post into a C# object.

"Bronze",
[
  228,
  380  
]

C# Object Structure:

public Score 
{
  public string Grade {get;set;} // Bronze, Silver, Gold
  public int PotentialPoints {get;set;} // First Integer
  public int ActualPoints {get;set;} // Second Integer
}

The Feed

The string "Bronze" is variable, but the integer array structure will stay the same [X,X].

[
   6,
   [
      [],
      4,
      {
         "time crunch":[
            "Bronze", <<< Trying to retrieve this node
            [
               228,
               380  
            ]
         ],
         "3 rides":[
            "Bronze", <<< Trying to retrieve this node
            [
               1418,
               2730
            ]
         ],
         "4 rides":[
            "Bronze", <<< Trying to retrieve this node
            [
               180,
               320
            ]
         ],
         "[2 rides,2 runs]":[
            "Silver", <<< Trying to retrieve this node
            [
               220,
               270
            ]
         ]
      }
   ]
]
2
  • Is the JSON structure will always be like the one mentioned in the question? Commented Jan 21, 2023 at 10:25
  • Yes. There will be additional data now shown within the 6, array but we don’t need that for now 😊 Commented Jan 21, 2023 at 10:40

2 Answers 2

3

If your JSON has a standard schema, you can extract the data with JSON path.

using Newtonsoft.Json.Linq;

var result = JArray.Parse(json).SelectToken("$.[1].[2]")
    .ToObject<Dictionary<string, JArray>>()
    .Select(x => new Score
        {
            Grade = x.Value.SelectToken("[0]").ToString(),
            PotentialPoints =  x.Value.SelectToken("[1].[0]").ToObject<int>(),
            ActualPoints =  x.Value.SelectToken("[1].[1]").ToObject<int>()
        })
    .ToList();

Demo @ .NET Fiddle

Sign up to request clarification or add additional context in comments.

2 Comments

Brilliant answer. If I wanted to retrieve the title, how would you approach that with the technique above? e.g. 4 rides
If using the same solution, you can refer to this Demo. As we convert the JToken to Dictionary (.ToObject<Dictionary<string, JArray>>()), we can extract "4 rides" with x.Key.
2

This could be done a lot better but with the JSON you provided, it works ...

public class Score 
{
    public string Name { get; set; }
    public string Grade { get; set; }
    public int PotentialPoints { get; set; }
    public int ActualPoints { get; set; }

    public Score()
    {
        Grade = string.Empty;
    }
}

static void ExtractNodes()
{
    string json = "[6,[[],4,{\"time crunch\":[\"Bronze\",[228,380]],\"3 rides\":[\"Bronze\",[1418,1244]],\"4 rides\":[\"Bronze\",[180,320]],\"[2 rides,2 runs]\":[\"Silver\",[220,270]]}]]";
    var jArray = JArray.Parse(json);

    var data = jArray.SelectTokens("$..*")
        .Where(x => x.Type == JTokenType.Array)
        .Where(x => x.First != null)
        .Where(x => x.First.Type == JTokenType.String)
        .Select(x => new Score()
        {
            Name = ((JProperty)x.Parent).Name,
            Grade = (String)x.First,
            PotentialPoints = (int)((JArray)x.Children().ElementAt(1)).Children().ElementAt(0),
            ActualPoints = (int)((JArray)x.Children().ElementAt(1)).Children().ElementAt(1)
        });
}

Feel free to wait for other answers.

4 Comments

With all due respect, I think the other answer is better and I won't be offended if you switch your answer. :-D
No problems. Actually, I need the header too! (e.g. 4 rides). How can I get that using your example above?
Answer updated to include the name property, call it what you want though.
You can traverse up and down no matter where you are. It's a brilliant framework.

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.