![](/img/trans.png)
[英]Filter a Dictionary by value where value is a list of string using LINQ
[英]LINQ filter by type on list from dictionary value
認為這是一個非常基本的問題,但這是我的第一個 LINQ 查詢,我完全陷入困境:
我有一個帶有字符串鍵和列表值的字典(請參見下面的定義),並且想要提取通過字典鍵選擇列表的特定類型列表的元素。
IDictionary<string, IList<MyBaseType>> dataItemMap;
MySubType 擴展 MyBaseType 的地方。
我狡猾的查詢是:
string identCode = "foo";
IEnumerable<MySubType> query =
from entry in dataItemMap
where entry.Key == identCode
select entry.Value.OfType<MySubType>();
以及錯誤消息(來自 LinqPad):
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<MySubType>>'
to 'System.Collections.Generic.IEnumerable<MySubType>'.
An explicit conversion exists (are you missing a cast?)
問題顯然出在 entry.Value.OfType<> 但如何指定列表元素? 我正在尋找類似 entry.Value.Items.OfType<> 的東西?
謝謝。
我想你想要這樣的東西:
IEnumberable<MySubType> query = dataItemMap[identCode].OfType<MySubType>();
這將獲取具有給定鍵的列表,然后對其進行過濾以僅返回 MySubType 元素。
編輯:我一直專注於為什么現有的解決方案不起作用(以及“我有每個元素的值列表,我想將其展平”的一般問題)而不是退后一步。 正如安迪的回答所示,您幾乎可以肯定地使用它是字典這一事實 - 將其從 O(n) 操作轉換為 O(1):)
兩個警告:
identCode
和字典鍵進行有序的、文化不敏感的比較; 使用字典查找將使用構造它的任何比較器。identCode
,您當前的代碼將返回一個空序列; 字典索引器會拋出異常。 如果您想避免這種情況,可以使用TryGetValue
。 請注意,如果您知道最后選擇的所有元素實際上都是正確的類型,那么使用Cast
可能比OfType
更好:
var query = dataItemMap[identCode].Cast<MySubType>();
當兩者都可以工作時,我通常更喜歡Cast
而不是OfType
,因為這意味着如果我對序列中數據的假設被證明是不正確的,我會通過異常而不是默默地丟失數據來發現它。
請注意, Cast
還將返回null
元素,而OfType
不會。
不,問題不在於使用OfType<>
- 而是您最終得到了一系列序列,但您試圖將其分配給單個序列。
要么更改返回類型,要么使用另一個from
子句來展平結果:
IEnumerable<MySubType> query = from entry in dataItemMap
where entry.Key == identCode
from value in entry.Value.OfType<MySubType>()
select value;
我很想直接使用擴展方法:
var query = dataItemMap.Where(e => e.Key == identCode)
.SelectMany(e => e.Value.OfType<MySubType>());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.