Using JavaScriptSerializer.DeserializeObject how can I get back a Dictionary that uses a case insensitive string comparer?
Asked Answered
P

2

8

I have some JSON that I need to deserialize so I'm using JavaScriptSerializer.DeserializeObject like:

var jsonObject = serializer.DeserializeObject(line) as Dictionary<string, object>;

The problem is that the Dictionary that comes back has a case-sensitive key comparer, but I need case-insensitive. Is there some way to get back a Dictionary that is case-insensitive?

EDIT: I'd prefer not to copy the data to a new structure, since I have a lot of data and this will be costly.

Polygyny answered 2/12, 2011 at 0:8 Comment(0)
A
10

Just create a new case insensitive dictionary and populate it with the current one.

var jsonObject = serializer.DeserializeObject(line) as Dictionary<string, object>;
var caseInsensitiveDictionary = new Dictionary<string, object>(jsonObject, StringComparer.OrdinalIgnoreCase);

[UPDATE] Test code:

    Stopwatch stop1 = new Stopwatch();
    Stopwatch stop2 = new Stopwatch();

    //do test 100 000 times
    for (int j = 0; j < 100000; j++)
    {
        //generate fake data
        //object with 50 properties
        StringBuilder json = new StringBuilder();
        json.Append('{');
        for (int i = 0; i < 100; i++)
        {
            json.Append(String.Format("prop{0}:'val{0}',", i));
        }
        json.Length = json.Length - 1;
        json.Append('}');

        var line = json.ToString();

        stop1.Start();
        var serializer = new JavaScriptSerializer();
        var jsonObject = serializer.DeserializeObject(line) as Dictionary<string, object>;
        stop1.Stop();

        stop2.Start();
        var caseInsensitiveDictionary = new Dictionary<string, object>(jsonObject, StringComparer.OrdinalIgnoreCase);
        stop2.Stop();
    }

    Console.WriteLine(stop1.Elapsed);
    Console.WriteLine(stop2.Elapsed);
    Console.Read();

The result is:

Deserializtion time: 1 min 21 sec

Dictionary creation time: 3 sec

So, the main proble is deserializtion. Dictionary creation is about 4%

Ammonal answered 2/12, 2011 at 0:18 Comment(5)
Thanks. I should note that I'd really like to avoid doing that. I will have 500GBs of JSON data (not all in one object), and avoiding extra data movement, to save time, is a big win. As a last resort I may have to, but I'm willing to write a fair bit of code to save time.Polygyny
@Kang Su I doubt that you will have performance problems with this code. Amount of data is not a problem. The time is increased with increasing of number of objects. How many keys do you have in your dictionary? I would recoment you to test this code before the writing of extra code.Ammonal
Probably for any given object no more than 50 keys. But there are millions of JSON objects, so I'll have to do this millions of times. Maybe I'll try and find out, but it would be nice if there was some way to get a Deserialized dictionary that was case-insensitive.Polygyny
Thanks Egor for the timing. I think 4% may be workable for me. At least its worth starting with and I can do something different if profiling shows that this 4% is the difference between acceptance. Thanks. Marking as answer.Polygyny
I googled this 4 years after you answered it, and it is still the best answer!Octamerous
M
0

I would recommend creating a new class that inherits from Dictionary<string, object> and in the constructor of this class, assign the case-insensitive comparer. I don't think it can be serialized to and from JSON.

Moynihan answered 2/12, 2011 at 0:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.