Reputation: 4535
I have a Dictionary defined as <int, IEnumerable<char>>
. Lets say the data is populated like:
1, a b c d e
2, f g h i j
3, k l m n o
If I have an IEnumerable consisting of 1 & 3, what would the LINQ look like to return 'a b c d e k l m n o'
(assuming space represents an iteration).
Upvotes: 2
Views: 547
Reputation: 13579
SelectMany is indeed what you want, but IMHO it's more readable to use the comprehension syntax and let it do the mapping for you, so something like:
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;
It's easier (again, IMHO) to toss an 'orderby' in there as well if/as needed.
Of course, if you find the extension method version simpler to read/parse, then by all means, use that instead. :)
Upvotes: 5
Reputation: 754545
It's unclear if you want only the 1 & 3 lines or all of them (1, 2 and 3). Here's the solution for both
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)
Upvotes: 0
Reputation: 837936
If you want a KeyNotFoundException if a key is not found:
IEnumerable<char> result = keys.SelectMany(key => d[key]);
If you want to silently ignore keys that are not found:
IEnumerable<char> result = keys.Where(key => d.ContainsKey(key))
.SelectMany(key => d[key]);
Upvotes: 3
Reputation: 26843
You need a Where
clause to filter the keys contained in the dictionary, and a SelectMany
clause to get a single enumerable list from each list contained in the dictionary.
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]);
Note that the second query will throw an exception if you have a key in the keys
enumerable that doesn't exist in your dictionary.
Upvotes: 0
Reputation:
As you mentioned in your comment, you can use a SelectMany
to aggregate an IEnumerable
of IEnumerable
s into a single IEnumerable
. However, you can also use Concat
to combine two separate collections into a single selection (or you can chain it to combine as many as you'd like).
Upvotes: 0
Reputation: 51319
Assuming that you have
var someEnumerables = new Dictionary<int, IEnumerable<char>>();
then
// Flattened will be an enumeration of the values ordered first by the key
var flattened = someEnumerables.OrderBy(kvp => kvp.Key).SelectMany(kvp => kvp.Value)
Upvotes: 0