In C# how do I filter a SortedDictionary using LINQ producing a subset which also is a SortedDictionary? Eg. I'd like to write
SortedDictionary<int, Person> source = ..fetch..
SortedDictionary<int, Person> filtered = source.Where(x=>x.foo == bar)
The only way I've found is to create a helper method and use that
SortedDictionary<TKey, TValue> SubDictionary<TKey, TValue> IEnumerable<KeyValuePair<TKey, TValue>> l)
{
SortedDictionary<TKey, TValue> result = new SortedDictionary<TKey, TValue>();
foreach (var e in l)
re开发者_高级运维sult[e.Key] = e.Value;
return result;
}
...
SortedDictionary<int, Person> source = ..fetch..
SortedDictionary<int, Person> filtered = SubDictionary(source.Where(x=>x.foo == bar))
If you want a one-statement solution, this will work:
SortedDictionary<int, Person> filtered =
new SortedDictionary<int, Person>(
source.Where(x => x.Value.foo == bar)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
However, it is inefficient, as it creates two dictionary objects (the ToDictionary() extension method creates one, which is then passed to the SortedDictionary constructor).
Your helper method will result in better performance. For cleaner syntax, you could make it an extension method on IEnumerable<KeyValuePair<TKey, TValue>>:
public static class KeyValuePairEnumerableExtensions
{
public static SortedDictionary<TKey, TValue> ToSortedDictionary<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> l)
{
SortedDictionary<TKey, TValue> result = new SortedDictionary<TKey, TValue>();
foreach (var e in l)
result[e.Key] = e.Value;
return result;
}
}
which can be used like this:
var f2 = source.Where(x => x.Value.foo == bar).ToSortedDictionary();
精彩评论