簡體   English   中英

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM