我试图返回与特定条件(由lookupKey数组中的元素所定义)匹配的List(lookupData)中的一个元素。
但是,如果将输出定义为IEnumerable类型,则不会返回任何结果。当i = 2时,“ Output”变量在最后一个循环处重置。为什么不起作用?
由于效率更高,我想将输出变量设置为IEnumerable而不是List。
var lookupKey = new string[] { "Male", "China" };
var lookupData = new List<string[]>();
lookupData.Add(new string[] { "Male", "China" });
lookupData.Add(new string[] { "Male", "America" });
lookupData.Add(new string[] { "Female", "UK" });
IEnumerable<string[]> output = lookupData;
for (int i = 0; i < 2; i++)
{
output = output.Where(x => x[i] == lookupKey[i]);
}
答案 0 :(得分:2)
i
循环变量未按照您的预期方式捕获。解决方案是在循环内引入局部变量:
for (int i = 0; i < 2; i++)
{
var index = i;
output = output.Where(x => x[index] == lookupKey[index]);
}
有关捕获循环变量的更多信息,请参见此处:Captured variable in a loop in C#
答案 1 :(得分:1)
简单来说,当您在lambda中使用变量时,它将变量的范围扩展到lambda /即使在for循环结束并且您对i的引用(在for中建立)之后,lambda仍然可以访问i循环初始化程序,已超出范围。
由于仅当您请求结果/枚举可枚举时(可能会在数小时后),lambda的LINQ执行才会真正发生,因此lambda将看到i
的值,因为它是由for循环留下的,即2,这意味着您的Lambda遇到的索引超出范围
在最新版本的C#中,修改了foreach循环的内部行为,以便循环的每次迭代都从被迭代的内容返回变量的副本,因此您应该能够将lookupKey的for更改为foreach它将按您期望的那样工作。尽管这是一种阅读和理解的尴尬模式,但我认为您应该考虑将其更改为以下内容:
var output = lookupData.Where(arr => arr.SequenceEquals(lookupKey));
如果数据集很大并且经常搜索,请考虑使用一个将项目散列的容器,因为现在此方法需要大量的字符串比较-lookupData中的条目数乘以lookupKey中的条目数
答案 2 :(得分:0)
您可以使用LINQ中的Where()
,All()
和Contains()
:
var output = lookupData
.Where(data => data.All(item => lookupKey.Contains(item)))
注意:如果您希望结果是List<string[]>
而不是IEnumerable<string[]>
,请在查询末尾添加ToList()
。
答案 3 :(得分:0)
您的搜索逻辑不太正确,您不需要for
循环,因为它会覆盖where
条件。这是一种可能的搜索方式,它将返回IEnumerable<string[]>
:
var output = lookupData.Where(g => g[0] == lookupKey[0] && g[1] == lookupKey[1]);
答案 4 :(得分:0)
使用SELECT p.id AS product_id, count(users.id) AS num_users
FROM products p
LEFT JOIN users ON p.id = users.product_id AND users.account_id = 1
GROUP BY p.id
ORDER BY p.id
代替List<string[]>
。由于IEnumerable<string[]>
将在需要获取值(例如Count()或Loop)时执行查询。因此,在情况为条件的for循环之后,当您尝试在此时IEnumerable<string[]>
对象上循环时,它将评估IEnumerable
。因此,这里的i = 3。
这是造成您问题的原因。
如果您使用.Where(x => x[i] == lookupKey[i])
,它将在您使用的for循环内立即计算表达式。
您更新的代码如下所示。
List<string[]>
IEnumerable vs List - What to Use? How do they work?希望这个答案可能会有所帮助。