简体   繁体   中英

Why doesn't this LINQ Select expression work

I've got a difficult LINQ expression and I can't figure out why it doesn't work. The syntax error I get is

The type of arguments for Enumerable.Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>) cannot be inferred from the usage. Try specifying the type arguments explicitly.

The error is on the second Select statement, x.Select . I'm trying to grab one element in each List of List from allFactors and add them together and keep each of each grouping that was added together in tempList . In other words, I want to keep the individual elements together in tempList and know their total in temp .

Earlier in the code allFactors is filled with values. How can I specify the types explicitly or do this another way. I can't understand why it doesn't infer the types either.

int temp = 0;
//List<List<int>> allFactors = new List<List<int>>();
List<int> tempList = new List<int>();
allFactors.Select(x => x.Select(y => { temp += y; tempList.Add(y); }));

EDIT: David L's answer does fix the syntax error! Unfortunately with further testing I realize that my code isn't doing what I wanted it to do. What I really want is to get every permutation whereby each group is made of only one element from a list of lists. As an example:

List<List<int>> oldList = {{1,2},{3,4}};
List<List<int>> newList = {{1,3},{1,4},{2,3},{2,4}};

I'm looking for some way to convert oldList into newList . The challenge is that I don't know how many nested lists there will be or how many items will be in each list. Any ideas? Thanks for everyone's thoughts so far.

The type cannot be inferred because you are not returning anything by the inner select. The compiler doesn't have anything to infer for the outer select as a result.

In addition, since you are not using the selected return, you could use .ForEach() instead.

int temp = 0;
List<List<int>> allFactors = new List<List<int>>();
List<int> tempList = new List<int>();
allFactors.ForEach(x => x.ForEach(y => { temp += y; tempList.Add(y); }));

If you wanted to stick with .Select() , you would need to return the value from the inner select and use .SelectMany() for the outer select.

int temp = 0;
List<List<int>> allFactors = new List<List<int>>();
List<int> tempList = new List<int>();
List<int> selectedList = allFactors.SelectMany(x => x.Select(y => 
                { 
                    temp += y;    
                    tempList.Add(y); 
                    return y; 
                })).ToList();

This would produce a "flattened" List<int> , which seems to be in line with your end goal for tempList .

If you want just flatten the "allFactors" you can go this way:

        var tempList = allFactors.SelectMany(x => x).ToList();
        var temp = tempList.Sum();

If you need only first element of each list, then it will be:

        var tempList = allFactors.Select(x => x.First()).ToList();
        var temp = tempList.Sum();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM