2

With JsonValueKind.Object you can use:

value.GetProperty("XXX")

With JsonValueKind.Array you can use:

value.EnumerateArray().ElementAtOrDefault(2)

But is it also possible to get a specific index without enumerating the array?

The reason is that this is called in a tight loop.

I could read all values and cache them in a dictionary myself, but as I read that System.Text.Json is specifically made for performance I don't want to allocate unnecessary dictionaries.

Here's an example.

static void Main(string[] args)
{
    var json = JsonSerializer.Deserialize<JsonElement>(@"[ ""item1"", ""item2""]");

    // (seems) to enumerate the whole object - so slow in loops with large arrays
    var test1 = json.EnumerateArray().ElementAtOrDefault(1);

    // FIXME: crashes
    var test2 = json.GetProperty("1");

    // would love to have (return null when not existing - does not enumerate array - dictionary-like performance)
    // var test3 = json.GetElementAt("1"); 
}

Note that

  • the actual code is called in a tight loop - it needs close to O(1) performnce
  • the array can be quite large (not just two elements)
7
  • Please, share the appropriate code Commented May 4, 2020 at 10:08
  • ArrayEnumerator implements IEnumerable<JsonElement>, you can cast to list or use linq to get any element, as you've already done Commented May 4, 2020 at 10:50
  • Hi @PavelAnikhouski, see the question - in theory I can do that, but as the System.Text.Json is specifically designed for performance I would rather prevent this if it's necessary - saving an extra dictionary allocation. Commented May 4, 2020 at 10:51
  • Not sure you can. If you look at the reference source, JsonDocument contains a ReadOnlyMemory<byte> _utf8Json; field and a MetadataDb parsedData field. And MetadataDb seems to basically be metadata about where to find properties and elements in the JSON. Commented May 8, 2020 at 18:13
  • 2
    You can get direct access to the value at a specific index, using the indexer on JsonElement (so for example value[2]). However, it won't always be O(1), and that is the side effect of the non-allocating design. @DirkBoer - let me know if this answers your question. learn.microsoft.com/en-us/dotnet/api/… Commented May 14, 2020 at 23:18

0

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.