j.ruiz
j.ruiz

Reputation: 13

How can I filter a nested dictionary using LINQ in C#?

How can I filter a nested dictionary using LINQ in C#?

This is the dictionary that I'm starting with:

Dictionary<string, Dictionary<string, string>> countriesByContinentDictionary = new Dictionary<string, Dictionary<string, string>>
{
    {
        "Europe", 
        new Dictionary<string, string> {
            { "0", "France" },
            { "1", "Germany"},
            { "2", "Switzerland" }
        } 
    },
    {
        "Asia",
        new Dictionary<string, string>
        {
            {"zero", "India" },
            {"1", "Pakistan" },
            {"2", "Russia" }
        }
    },
    {
        "Africa",
        new Dictionary<string, string>
        {
            { "0", "South Africa" },
            { "1", "Nigeria" },
            { "2", "Lybia"}
        }
    }
};

I'm trying to filter to countries that have the letter r. This is what I'm trying to get it to look like after the filtering:

Dictionary<string, Dictionary<string, string>> countriesByContinentDictionary = new Dictionary<string, Dictionary<string, string>>
{
    {
        "Europe", 
        new Dictionary<string, string> {
            { "0", "France" },
            { "1", "Germany"},
            { "2", "Switzerland" }
        } 
    },
    {
        "Asia",
        new Dictionary<string, string>
        {
        }
    },
    {
        "Africa",
        new Dictionary<string, string>
        {
            { "0", "South Africa" },
            { "1", "Nigeria" }
        }
    }
};

This is the code I have so far:

public static Dictionary<string, Dictionary<string, string>> GetRecordsContainingSubStringWithLambda(Dictionary<string, Dictionary<string, string>> originalNestedDictionary, string lambdaSubString)
{
    var filteredNestedDictionary = Enumerable.Range(0, originalNestedDictionary.Count)
        .Select(
                row => Enumerable.Range(0, originalNestedDictionary.ElementAt(row).Value.Count)
                .Select(col => originalNestedDictionary.ElementAt(row).Value.ElementAt(col))
                .Where(keyValuePair => keyValuePair.Value != null && keyValuePair.Value.Contains(lambdaSubString))
                .ToDictionary<string, string>(keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value)
        ).ToDictionary<string, Dictionary<string, string>>(keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value);
    return filteredNestedDictionary;
}

But I'm getting the following error:

error CS0029: Cannot implicitly convert type 'System.Collections.Generic.Dictionary<System.Collections.Generic.Dictionary<string, string>, string>' to 'System.Collections.Generic.Dictionary<string, System.Collections.Generic.Dictionary<string, string>>'

Upvotes: 1

Views: 375

Answers (1)

AlphaModder
AlphaModder

Reputation: 3386

Note that Dictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>> directly, so there is no need for us to count indices. Instead, use Select to transform each item in the outer dictionary and Where to filter out inner items that do not match the filter, like so:

public static Dictionary<string, Dictionary<string, string>> GetRecordsContainingSubStringWithLambda(Dictionary<string, Dictionary<string, string>> originalNestedDictionary, string lambdaSubString)
{
    return originalNestedDictionary.Select(outerPair => new KeyValuePair<string, Dictionary<string, string>>(
        outerPair.Key,
        outerPair.Value
            .Where(innerPair => innerPair.Value != null && innerPair.Value.Contains(lambdaSubString))
            .ToDictionary(innerPair => innerPair.Key, innerPair => innerPair.Value)
    )).ToDictionary(outerPair => outerPair.Key, outerPair => outerPair.Value);
}

Upvotes: 1

Related Questions