Reputation: 3071
After reading this answer https://stackoverflow.com/a/902123 I wanted to check out how LINQ would work on multi-dimensional lists, so here is some test code that I just can not get right.
class Program
{
static void Main(string[] args)
{
// Two dimensional list of ints
var arr = new List<List<int>>();
var rand = new Random();
// fill the array with random values, this works fine.
for (int i=0; i<10; i++)
{
arr.Add(new List<int>());
for (int k=0; k<5; k++)
{
arr[i].Add( rand.Next(1, 21) );
}
}
var q = from int e in arr select e;
List<int> lst = q.ToList(); // This fails with InvalidCastException
// here I would like to pretend that the list is one dimensional
foreach (int i in lst)
{
Console.WriteLine(i);
}
}
The idea is that the list should look like it has only one dimension, after I cast the query back to List< int >.
What might be the cause of the problem:
Visual studio tells me that 'q' has type
{System.Linq.Enumerable.WhereSelectEnumerableIterator< int, int >}
Whereas the answer I linked to at the top of this question states that 'q' should have type
IEnumerable< int >
Question 1: Why is the exception thrown?
Question 2: How can I convert multi-dim list to one dimensional list with LINQ?
Thank you.
Upvotes: 0
Views: 4369
Reputation: 1534
In you query from int e in arr select e
You are trying to get int value from arg
while each value of your arg
is List<int>
. Thats why you get InvalidCastException
because it can not cast List<int>
to int
. If you want to get value from internal List<int>
you can use query arg.Select(list => list).Select(val => val)
Upvotes: 0
Reputation: 68635
Answer 1:
I think like this:
var q = from int e in arr select e;
This is your code where your have wroten a query which will be executed later.
List<int> lst = q.ToList();
In this code you are calling your query to execute and then make .ToList()
.
Here you have declared a statement like this:
var arr = new List<List<int>>();
but in the query your trying to cast its content which is as List<int>
to int
,so this is why your are getting exception InvalidCastException
.
Your incorrect code is in
var q = from int e in arr select e;
Here e
is a List a your are trying to cast it to int
and so you have your exception
Answer 2:
Change your code like this:
var q = from e in arr
from i in e select i;
List<int> lst = q.ToList();
Upvotes: 2
Reputation: 3502
Just modify your code as shown below and check if that work as you expected:
for (int i=0; i<10; i++)
{
arr.Add(new List<int>());
for (int k=0; k<5; k++)
{
arr[i].Add( rand.Next(1, 21) );
}
}
//var q = from int e in arr select e; Remove this line
List<int> lst = arr.SelectMany(it=>it).ToList(); //This will flatten the result set
Upvotes: 0
Reputation: 6766
1. Why is the exception thrown?
from e in arr select e;
instead of
from int e in arr select e;
It was throwing exception because you were attempting to cast List<int>
to int
. More ever linq is smart enough to identify the type of variable do not specify it explicitly is recommended practices.
2. How can I convert multi-dim list to one dimensional list with LINQ?
make a use of selectMany method for above case.
List<int> lst = q.SelectMany(d => d).ToList();
Here is .net fiddle for your reference.
Upvotes: 5