public List<SavedOption> GetValidSavedOptions(
List<Option> itemOptions,
List<SavedOption> savedOptions)
{
List<SavedOption> finalSavedOptions = savedOptions.Where(x =>
OptionTextDoesMatch(y, x) &&
itemOptions.Any(y => y.SomeID == x.SomeID)
).ToList();
}
我对LINQ和Lambdas完全不熟悉。
在上文中,只有在列表中找到对SavedOption
的{{1}}和OptionTextDoesMatch
的调用时,我才需要/想要执行的操作包括SomeID
savedOption
中的SomeID
。如果对itemOptions
的调用返回OptionTextDoesMatch
并且在true
集合中找到了当前savedOptions
SavedOption.SomeID
,那么它将在itemOption
< / p>
更新:
我试过这个,但语法仍然不适合我:
savedOptions.Where(itemOptions.Any(OptionTextDoesMatch(x,y)&amp;&amp;(y =&gt; y.SomeID == x.SomeID)))。ToList();
现在我不知道我是否可以像这样投入x。我假设如果我这样做将代表currrent savedOption并且我不需要=&gt; ?
答案 0 :(得分:6)
虽然上面的答案正确,但它们是“给人一条鱼”的答案。最好借此机会学习如何将问题分解成小块,然后将结果重新组合成查询。
在上面,我需要/想要做什么 只有在包含SavedOption时才包括 调用OptionTextDoesMatch和SomeID 在...中找到savedOption的 itemOptions中的SomeID列表。
让我试着改写一个令人困惑的句子。
您有SavedOptions列表。每个SavedOption都有一个ID和一些文本。
您有一个选项列表。每个选项都有一个ID和一些文本。
您希望过滤SavedOptions列表,以获取与BOTH文本和ID上的某些选项匹配的SavedOptions。
打破问题。假设您没有SavedOptions序列。假设您只有一个SavedOption和一个Options列表。你怎么知道它是否匹配?
这很简单:
SavedOption mySavedOption = whatever;
bool matchExists = itemOptions.Any(item=>
OptionTextDoesMatch(item, mySavedOption) &&
item.SomeID == mySavedOption.SomeID);
这有意义吗?
现在假设您想要使用SavedOption创建一个谓词。你会怎么做?这很简单:
Func<SavedOption, bool> predicate = savedOption =>
itemOptions.Any(item=>
OptionTextDoesMatch(item, savedOption ) &&
item.SomeID == savedOption.SomeID);
这是谓词,用于确定单个项是否匹配。
还有意义吗?如果有些事情让人感到困惑,请阻止我。
因此,要从中删除过滤器,将谓词应用于已保存选项列表中的每个项目:
result = savedOptions.Where(savedOption =>
itemOptions.Any(item=>
OptionTextDoesMatch(item, savedOption) &&
item.SomeID == savedOption.SomeID));
或者,在查询理解表单中,我个人觉得更容易阅读。
result = from savedOption in savedOptions
where itemOptions.Any(item =>
OptionTextDoesMatch(item, savedOption) &&
item.SomeID == savedOption.SomeID)
select savedOption;
但可能更好的选择是使用连接。 连接只是对两个与ID相关的集合的笛卡尔积的过滤器进行优化。
result = from savedOption in savedOptions
join itemOption in itemOptions
on savedOption.SomeID equals itemOption.SomeID
where OptionTextDoesMatch(itemOption, savedOption)
select savedOption;
这是清楚的吗?
答案 1 :(得分:3)
随机猜测:
List<SavedOption> finalSavedOptions = savedOptions.Where(x =>
itemOptions.Any(y => OptionTextDoesMatch(y, x) && y.SomeID == x.SomeID)
).ToList();
答案 2 :(得分:1)
在你的Where子句中,你在savedOptions方法中迭代每个对象 - 就像你做的那样:
foreach(SavedOption x in savedOptions)
{
if (OptionTextDoesMatch(y, x)) //y is not yet specified...
{
foreach(Option y in itemOptions)
{
if (y.SomeID == x.SomeID)
yield return x;
}
}
}
在您的语句中,where
子句迭代您的savedOptions列表,并且每次迭代都会将savedOption的当前实例分配给'x'。然后,您正在检查'x的文本是否与您尚未指定的内容相匹配 - 'y'。
然后你进行第二次迭代:itemOptions.Any(y => y.SomeID == x.SomeID)
。在这里,您已经指定y
现在被定义为Option
的实例,其方式与使用外部lambda表达式的方式非常相似:
foreach(Option y in itemOptions)
{
return y.SomeID == x.SomeID;
}
因为外部子句指定了x
,所以我们可以在内部子句中访问它,但事实并非如此。在内部子句之前未指定y
,因此您的where
子句不起作用。
为了全面诊断你想要做什么,我需要了解Option和SavedOptions对象的样子,并弄清楚你在逻辑上想要做什么才能准确解释你的lambda应该看起来......
我怀疑你真正想做的事情是:
foreach(SavedOption x in savedOptions)
foreach(Option y in itemOptions)
if (OptionTextDoesMatch(y, x) && (y.SomeID == x.SomeID))
yield return x;
lambda表示法将是:
return savedOptions.Where(x => itemOptions.Any(y => OptionTextDoesMatch(y, x) && (y.SomeID == x.SomeID)));