2011-09-23 95 views
2

我有一個詞典定義爲<int, IEnumerable<char>>。可以說,數據填充,如:LINQ將多個IEnumerables聚合成一個?

1, a b c d e 
2, f g h i j 
3, k l m n o 

如果我有一個IEnumerable由1 & 3,會是什麼LINQ看起來好像回到'a b c d e k l m n o'(假設空間表示迭代)。

+1

Bah它的SelectMany。 –

+0

你可以發佈這個答案嗎?與SelectMany相關的任何內容都可能很有趣,因爲該功能令人困惑:) –

+1

備忘單:'Select' =「map」,'SelectMany' =「flatmap」,'Where' =「filter」,'Concat' =「append」 - 這是我在自己的頭上使用的;-) – 2011-09-24 00:01:53

回答

5

的SelectMany的解決方案確實是你想要的,但恕我直言,這是更具可讀性用理解語法,讓它爲你做的映射,所以像:

var dict = ... // dictionary 
var keys = ... // enumerable with 1 and 3 in it 
var result = from key in keys 
      from val in dict[key] 
      select val; 

這是更容易(再次,恕我直言)拋出'orderby'在那裏以及/如果需要。

當然,如果您發現擴展方法版本更易於讀取/解析,那麼請務必使用該方法。 :)

0

假設你有

var someEnumerables = new Dictionary<int, IEnumerable<char>>(); 

然後

// Flattened will be an enumeration of the values ordered first by the key 
var flattened = someEnumerables.OrderBy(kvp => kvp.Key).SelectMany(kvp => kvp.Value) 
+1

+0的SelectMany示例;正確地顯示了「SelectMany」的使用,但沒有解決OP按照鍵列表進行過濾的要求。 –

+0

沒有捕捉到OQ的那部分,好的呼叫。 –

0

你需要一個Where子句來過濾包含在字典中的按鍵和一個SelectMany子句,以獲得從每個列表中的一個枚舉列表包含在字典中。

Dictionary<int, IEnumerable<char>> dict; // contains all of your key-value pairs 
IEnumerable<int> keys; // contains the keys you want to filter by 

IEnumerable<char> data = dict.Where(kvp => keys.Contains(kvp.Key)) 
          .SelectMany(kvp => kvp.Value); 

// or, alternatively: 

IEnumerable<char> data = keys.SelectMany(i => dict[i]); 

請注意,如果您有不中你的字典存在keys枚舉按鍵上的第二查詢會拋出異常。

+0

你真的應該從'keys'集合構建而不是通過字典中的所有項目。 –

+0

你是對的;我添加了一個更簡潔的方式來做到這一點,並附有免責聲明。 –

0

正如您在評論中提到的,您可以使用SelectManyIEnumerableIEnumerable s合併爲一個IEnumerable。但是,您也可以使用Concat將兩個單獨的集合合併到一個選擇中(或者可以將它鏈接成儘可能多的組合)。

2

如果你想有一個KeyNotFoundException如果密鑰沒有發現:

IEnumerable<char> result = keys.SelectMany(key => d[key]); 

如果你想靜靜地忽略未找到鑰匙:

IEnumerable<char> result = keys.Where(key => d.ContainsKey(key)) 
           .SelectMany(key => d[key]); 
0

,如果你只想要1目前還不清楚& 3行或全部(1,2和3)。下面是兩個

Dictionary<int, string> map = ...; 
// 1 and 3 only 
IEnumerable<char> result1 = map 
    .Where(x => x.Key == 1 || x.Key == 3) 
    .OrderyBy(x => x.Key) 
    .SelectMany(x => x.Value) 

// All 
IEnumerable<char> result2 = map 
    .OrderyBy(x => x.Key) 
    .SelectMany(x => x.Value)