[英]How to perform 2 checks in LINQ Where
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
只有當該呼叫OptionTextDoesMatch
和SomeID
中的savedOption
中的列表中找到SomeID
在itemOptions
。 如果對OptionTextDoesMatch
的調用返回true
,並且在itemOption
集合中找到了當前的savedOptions
SavedOption.SomeID
,則它將位於ToList()
更新:
我試過了,但是語法仍然對我不起作用:
savedOptions.Where(itemOptions.Any(OptionTextDoesMatch(x,y)&&(y => y.SomeID == x.SomeID)))。ToList();
現在我不知道我是否可以像這樣扔x。 我假設如果我這樣做將代表當前的saveOption,並且我不需要=>?
盡管以上答案是正確的 ,但它們是“給人一條魚”的答案。 最好借此機會學習如何將問題分解成小塊,然后將結果重新組合成查詢。
在上面,僅當在itemOptions的SomeID列表中找到對OptionTextDoesMatch和saveOption的SomeID的調用時,我需要/想要做的就是包括SavedOption。
讓我嘗試改寫這個令人困惑的句子。
您有一個SavedOptions列表。 每個SavedOption都有一個ID和一些文本。
您有一個選項列表。 每個選項都有一個ID和一些文本。
您希望過濾SavedOptions列表,以獲取與文本和ID上的某些Option匹配的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;
明白了嗎?
隨機猜測:
List<SavedOption> finalSavedOptions = savedOptions.Where(x =>
itemOptions.Any(y => OptionTextDoesMatch(y, x) && y.SomeID == x.SomeID)
).ToList();
在Where子句中,您要像使用以下方法一樣,在saveOptions方法中迭代每個對象:
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列表,並且對於每次迭代,將saveOption的當前實例分配為'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)));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.