Search code examples
c#json.netjson.netjson-query

How to get access the last item of a JSON array using Newtonsoft.Json SelectToken method


Is there a way to get the last item of a JSON array using a JSON query only (in this case Newtonsoft.Json SelectToken method)?

I can not use the Last method from Newtonsoft.Json, as I get the query from a frontend textbox and the only one who knows about structure of the JSON document is the user themself. They may want to get last item of an array in some of their JSON queries.

If the only choice is to use this Last method, I would need to add an override of SelectToken which accepts queries with a negative index and split normal and minus queries and then run these split sections in Last or SelectToken methods which is not a good solution for me.

I tried multiple syntaxes with SelectToken but I got exceptions (embeded in comments):

var jsonArray = @"[{""Name"":""amir0"",""Id"":0},{""Name"":""amir1"",""Id"":1}]";
var array = JArray.Parse(jsonArray);
        
Console.WriteLine(array.SelectToken("[-1].Name")); //Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range.
Console.WriteLine(array.SelectToken("[^1].Name")); //Unhandled exception. Newtonsoft.Json.JsonException: Unexpected character while parsing path indexer: ^

Solution

  • If you look at the JSONPath documentation, there are two examples of how to get the last element with SelectToken, though only one of them is actually supported in Newtonsoft.Json (Issue):

    var jsonArray = @"[{""Name"":""amir0"",""Id"":0},{""Name"":""amir1"",""Id"":1}]";
    var array = JArray.Parse(jsonArray);
            
    Console.WriteLine(array.SelectToken("[-1:].Name"));
    
    // Theoretically valid syntax, but not supported
    Console.WriteLine(array.SelectToken("[(@.length-1)].Name"));
    

    In short, use [-1:] to get the last element.