0

How do I read into a C# dictionary, a multilingual json lexicon in the form:

[{
  "Top": {
    "de-DE": "Oben",
    "fr-FR": "haut"
  }
},    {
  "Football": {
    "de-DE": "Fußball",
  },
},
{
  "Taxi": {
  }
}]

In the json file there is a key, and for each supported language, a property and value. Where the word in the target language is the same as the key, there is no property for that language under that key in the json file.

At startup we load into a C# dictionary only those entries for the user language. In this snippet, the dictionary for German should be

Top, Oben
Football, Fußball
Taxi, Taxi

In French

Top, Haut
Football, Football,
Taxi, Taxi

How do I read the json file into a C# dictionary? The dictionary is not huge ... hundreds rather than millions of entries, so performance is not critical.

9
  • 3
    You go to QuickType.io , paste a sample of Json in and hit the button that generates C# :) (they also have a vs extension that allows you to paste Json into VS and it appears as c# code) Commented Feb 16, 2020 at 7:15
  • The JSON you posted is not valid JSON. Did you miss the square brackets? Commented Feb 16, 2020 at 7:27
  • If you can change the structure, you could use a slightly different (and IMHO much better) structure in this example on .net fiddle Commented Feb 16, 2020 at 7:47
  • @SirRufo I'm not sure how your example would work as we support multiple languages, so although where there is no entry for de-DE there might be an entry for fr-FR and other languages. A missing property for one language does not allow us to set the element to null. Perhaps I've misunderstood? Commented Feb 16, 2020 at 8:18
  • I've updated my question to show a more complete example Commented Feb 16, 2020 at 8:28

2 Answers 2

2

The types

public class LocalizationInfo : Dictionary<string, string>
{
    public LocalizationInfo() : base( StringComparer.InvariantCultureIgnoreCase ) { }
}

public class LocalizationItem : Dictionary<string, LocalizationInfo>
{ }

public class LocalizationCollection : List<LocalizationItem>
{
    public Dictionary<string, string> GetLocalizedDict( string cultureName )
    {
        if ( cultureName is null )
        {
            throw new ArgumentNullException( nameof( cultureName ) );
        }

        return this
            .Where( e => e.Count == 1 )
            .Select( e => e.First() )
            .ToDictionary( e => e.Key, e => e.Value == null ? e.Key : e.Value.TryGetValue( cultureName, out var localizedValue ) ? localizedValue : e.Key );
    }

    public Dictionary<string, string> GetLocalizedDict( CultureInfo cultureInfo )
    {
        if ( cultureInfo is null )
        {
            throw new ArgumentNullException( nameof( cultureInfo ) );
        }

        return GetLocalizedDict(cultureInfo.Name);
    }

    public Dictionary<string, string> GetLocalizedDict(  )
    {
        return GetLocalizedDict( CultureInfo.CurrentCulture );
    }
}

and the use case

class Program
{
    static readonly string _json =
        "[{" + Environment.NewLine +
        "  \"Top\": {" + Environment.NewLine +
        "    \"de-DE\": \"Oben\"," + Environment.NewLine +
        "    \"fr-FR\": \"haut\"" + Environment.NewLine +
        "  }" + Environment.NewLine +
        "},    {" + Environment.NewLine +
        "  \"Football\": {" + Environment.NewLine +
        "    \"de-DE\": \"Fußball\"" + Environment.NewLine +
        "  }" + Environment.NewLine +
        "}," + Environment.NewLine +
        "{" + Environment.NewLine +
        "  \"Taxi\": {" + Environment.NewLine +
        "  }" + Environment.NewLine +
        "}]";

    static void Main( string[] args )
    {
        var data = JsonSerializer.Deserialize<LocalizationCollection>( _json );

        var frDict = data.GetLocalizedDict( "fr-fr" );
        var deDict = data.GetLocalizedDict( "de-de" );

        var dict = data.GetLocalizedDict();
    }
}

and a live example

BTW

I had choosen a structure like this

{
  "Top": {
    "de-DE": "Oben",
    "fr-FR": "haut"
  },
  "Football": {
    "de-DE": "Fußball"
  },
  "Taxi": {}
}

There is no need for an array with objects which only contain a single property.

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

Comments

1

I assumed your JSON is List of Array

[
  {
    "Top": {
      "de-DE": "Oben",
      "fr-FR": "haut"
    }
  },
  {
    "Football": {
      "de-DE": "Fußball"
    }
  },
  {
    "Taxi": {
    }
  }
]

You can use JsonConvert.DeserializeObject to convert the json to Dictionary

var results = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);

//DE Dictionary
var deDict = results.SelectMany(x => x).ToDictionary(x => x.Key, x => JObject.Parse(x.Value.ToString())["de-DE"] == null ? "" : JObject.Parse(x.Value.ToString())["de-DE"].ToString());

//FR Dictionary
var frDict = results.SelectMany(x => x).ToDictionary(x => x.Key, x => JObject.Parse(x.Value.ToString())["fr-FR"] == null ? "" : JObject.Parse(x.Value.ToString())["fr-FR"].ToString());

//DE Dictionary     
foreach (var keyvalue in deDict)
{
    Console.WriteLine($"{keyvalue.Key} : {keyvalue.Value}");
}

//FR Dictionary
foreach (var keyvalue in frDict)
{
    Console.WriteLine($"{keyvalue.Key} : {keyvalue.Value}");
}

OUTPUT

Top : Oben
Football : Fußball
Taxi :

Top : haut
Football :
Taxi :

3 Comments

The output in this case is not a dictionary:key-value pairs
@Vague, I have updated the post to push the results to Dictionary
@Vague, does this answer your question?

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.