Home > Net >  c# flatten a generic dictionary of lists with Linq - 'type arguments for method cannot be infer
c# flatten a generic dictionary of lists with Linq - 'type arguments for method cannot be infer

Time:07-09

Following this answer to somebody else's question, I am trying to make a method which will do this for a dictionary of any type

So far I have come up with the following function, but I am getting a 'type arguments for method cannot be inferred' on the SelectMany clause.

    public List<T> FlattenDictionary<T>(Dictionary<object, T> dictionary)
    {
        var list = dictionary.Values              // To get just the List<string>s
                 .SelectMany(x => x)  // Flatten
                 .ToList();           // Listify

        return list;

    }

Following the answer from @Ctznkane525, I have come up with the following:

    public List<T> FlattenListDictionary<I, T>(Dictionary<I, T> dictionary) where T : IEnumerable<T>
    {
        var list = dictionary.Values              // To get just the List<string>s
                 .SelectMany(x => x)  // Flatten
                 .ToList();           // Listify

        return (List <T>) list;
    }

This now compiles without any errors but I still can't use the function because I get an error. Take the following example:

        var dictionary = new Dictionary<int, List<string>>();
        var list_1 = new List<string>();
        list_1.Add("hello");
        list_1.Add("good morning");
        list_1.Add("hi");

        var list_2 = new List<string>();
        list_2.Add("cat");
        list_2.Add("dog");
        list_2.Add("mouse");

        dictionary[10] = list_1;
        dictionary[320] = list_2;

        var list = (List<string>) FlattenListDictionary(dictionary);

With our without the cast I get the following error:

The type 'System.Collections.Generic.List' cannot be used as a type parameter 'T' in the generic type or method 'FlattenListDictionary<I,T>(Dictionary<I,T>). There is no implicit reference conversion from System.Collections.Generic.List to System.Collections.Generic.IEnumerable<System.Collection.Generic.List>'.

I also tried changing

where T : IEnumerable<T>

to

where T : List<T>

but that didn't help

CodePudding user response:

In the other example, the value type of the dictionary is a list. You just need a similar constraint.

where T : IEnumerable - should do that.

public List<T> FlattenDictionary<T>(Dictionary<object, T> dictionary) where T : IEnumerable<T>
{
    var list = dictionary.Values              // To get just the List<string>s
                 .SelectMany(x => x)  // Flatten
                 .ToList();

    return list;

}

CodePudding user response:

Thinking you can achieve, without specifying the constraint.

public static List<T> FlattenListDictionary<I, T>(Dictionary<I, List<T>> dictionary)
{
    var list = dictionary.Values              // To get just the List<string>s
        .SelectMany(x => x)  // Flatten
        .ToList();           // Listify
        
    return list;
}

Calling method:

FlattenListDictionary(dictionary);

Sample NET Fiddle

  • Related