在阅读了这个答案后https://stackoverflow.com/a/902123我想看看LINQ如何在多维列表上工作,所以这里有一些我无法正确的测试代码。
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);
}
}
我的想法是,在我将查询转换回List&lt;之后,列表应该看起来只有一个维度。 int&gt;。
可能是问题的原因:
Visual Studio告诉我&#39; q&#39;有类型
{System.Linq.Enumerable.WhereSelectEnumerableIterator< int, int >}
虽然我在这个问题的顶部链接到的答案表明&#39; q&#39;应该有类型
IEnumerable< int >
问题1 :为什么抛出异常?
问题2 :如何使用LINQ将多维度列表转换为一维列表?
谢谢。
答案 0 :(得分:5)
<强> 1。为什么抛出异常?
from e in arr select e;
而不是
from int e in arr select e;
由于您试图将List<int>
投射到int
,因此抛出异常。更多linq足够聪明,可以识别变量的类型,而不是明确指定它是推荐的做法。
<强> 2。如何使用LINQ将多维度列表转换为一维列表?
在上面的情况下使用selectMany方法。
List<int> lst = q.SelectMany(d => d).ToList();
Here是.net小提琴,供您参考。
答案 1 :(得分:2)
回答1:
我想是这样的:
var q = from int e in arr select e;
这是您的代码,您可以在其中编写一个稍后将执行的查询。
List<int> lst = q.ToList();
在此代码中,您调用查询执行,然后调用.ToList()
。
在这里你宣布了一个这样的声明:
var arr = new List<List<int>>();
但在查询中,您尝试将其内容List<int>
转换为int
,因此这就是您获得异常InvalidCastException
的原因。
您的错误代码在
var q = from int e in arr select e;
此处e
是您尝试将其投放到int
的列表,因此您有例外
回答2:
更改您的代码:
var q = from e in arr
from i in e select i;
List<int> lst = q.ToList();
答案 2 :(得分:0)
只需修改您的代码,如下所示,并检查是否按预期工作:
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
答案 3 :(得分:0)
在您的查询中from int e in arr select e
您正试图从arg
获取int值,而arg
的每个值都是List<int>
。这就是为什么你得到InvalidCastException
因为它无法将List<int>
强制转换为int
的原因。如果您想从内部List<int>
获取价值,可以使用查询arg.Select(list => list).Select(val => val)