Search code examples
c#jsonjson.net

C# Iterate from Last JSON Object to First


Is there a good way to iterate through a deserialized JSON object from last to first? i.e., the following code I can iterate and record 'n' values from first to last until it meets my count condition for further processing:

protected void testButton_Click(object sender, EventArgs e)
    {

        List<decimal> priceHistory = new List<decimal>();

        
        var client = new RestClient("https://api.tdameritrade.com/v1/marketdata/" + inputSymbol + "/pricehistory?periodType=year&period=1&frequencyType=daily&frequency=1&needExtendedHoursData=false");
        client.Timeout = -1;
        var request = new RestRequest(Method.GET);
        request.AddHeader("Authorization", "Bearer " + ReadAccessToken());
        request.AddParameter("text/plain", "", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);

        dynamic history = JsonConvert.DeserializeObject<JObject>(response.Content);    

        int count = 0;    

        foreach (var child in history["candles"])
        {
            count += 1;

            while (count <= 100)
            {
                decimal close = child["close"];
                priceHistory.Add(close);
                break; 
            }
        }    

        decimal simpleMovingAverage = priceHistory.Average();

        responseLabel.Text = simpleMovingAverage.ToString();
      
        //output is taking the first 100 close prices returned from the JSON response and averaging those values. 

    }

However, what I cannot find a solution to is how to begin at the last nested JSON object and add values from a back-to-front style. I am trying to reverse the aggregation from counting first nested object + 'n' next values sequential to the previous down the list, to actually taking the last nested JSON object in the response and average it with each of its previous 'n' values until the count condition has been met.

EDIT

JSON example with arbitrary 'n' period for reference:

{
  "candles": [
    {
      "open": 172.51,
      "high": 176.36,
      "low": 171.5,
      "close": 171.86,
      "volume": 2292877,
      "datetime": 1582524000000
    },
    {
      "open": 172.18,
      "high": 172.945,
      "low": 165.8,
      "close": 166.65,
      "volume": 2358560,
      "datetime": 1582610400000
    },
    {
      "open": 168.28,
      "high": 169.38,
      "low": 165.61,
      "close": 166.92,
      "volume": 2545782,
      "datetime": 1582696800000
    },
    {
      "open": 164.4,
      "high": 166.55,
      "low": 159.96,
      "close": 159.99,
      "volume": 2957507,
      "datetime": 1582783200000
    },
    {
      "open": 155.29,
      "high": 158.92,
      "low": 152.66,
      "close": 156.48,
      "volume": 3053876,
      "datetime": 1582869600000
    },
    {
      "open": 157.92,
      "high": 164.0,
      "low": 156.55,
      "close": 163.92,
      "volume": 2532128,
      "datetime": 1583128800000
    }
  ],
  "symbol": "DE",
  "empty": false
}

Solution

  • You can use the Reverse() method of the JArray class. Just cast your history["candles"] JTokeninto a JArray, and call reverse.

    void ParseJson(string json)
    {
        var history = JObject.Parse(json);
        var candles = (history["candles"] as JArray).Reverse();
    
        foreach (var child in candles)
        {
            Console.WriteLine(child["close"].ToString());
        }
    
        Console.Read();
    }