LINQ将多个IEnumerables聚合成一个?

时间:2011-09-23 23:31:19

标签: c# linq

我将词典定义为<int, IEnumerable<char>>。假设数据填充如下:

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

如果我有一个由1&amp;组成的IEnumerable 3,LINQ看起来会返回'a b c d e k l m n o'(假设空格代表迭代)。

6 个答案:

答案 0 :(得分: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'更容易(再次,恕我直言)。

当然,如果您发现扩展方法版本更易于读取/解析,那么请务必使用它。 :)

答案 1 :(得分:2)

如果找不到密钥,则需要KeyNotFoundException:

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

如果您想静默忽略未找到的键:

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

答案 2 :(得分: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)

答案 3 :(得分: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枚举中的密钥,则第二个查询将抛出异常。

答案 4 :(得分:0)

正如您在评论中提到的,您可以使用SelectManyIEnumerable IEnumerableIEnumerable聚合到一个Concat中。但是,您也可以使用{{1}}将两个单独的集合合并为一个选择(或者您可以将其链接以组合您想要的任意数量)。

答案 5 :(得分:0)

目前还不清楚你是否只想要1&amp; 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)