C#/.NET/WPF: Obtaining subsets from LINQ, rather than the IEnumerable
I have some trivial code that looks like this:
SortedDictionary<String, long> d = new SortedDictionary<String, long>();
// d is then populated with an expensive time-consuming process
ListBox lb = new ListBox();
lb.ItemsSource = d; // THIS WORKS GREAT
Now what I'd like to do is dynamically show a subset of the dictionary without having to recompute it.
// min is assigned somewhere else
lb.ItemsSource = d.SkipWhile( kvp => kvp.Value < min ); // THIS DOESN'T WORK
.SkipWhile() returns an IEnumerable, which is great for foreach loops, but not so hot for ItemsSource.
A) Is there a way to pass a LINQ-like expression to a WPF control in this manner?
B) Failing that, is there a way to do something like:
// Put things back, like the .ToArray() syntax
d.SkipWhile( kvp => kvp.Value < min).ToSortedDictionary();
C) Failing that, is there a way to remove entries from the actual dictionary conditionally?
d.RemoveWhere( kvp => kvp.Value < min );
UPDATE:
The filtering wasn't working from what I was expecting. Turns out my understanding of .SkipWhile() was incorrect based on a bum documentation source.
// This is what I was se开发者_JAVA百科eing and seemed strange
Console.WriteLine("Total = " + dict.Count");
Console.WriteLine(" Skip = " + dict.SkipWhile( kvp => kvp.Value < 3 ).Count());
foreach ( var kvp in dict.SkipWhile( kvp => kvp.Value < 3 ) ) {
Console.WriteLine( kvp );
}
Resulted in:
Total = 33350
Skip = 33350
[ 0, 1042 ]
[ 00, 52 ]
[ 000, 55 ]
[ 001, 1 ]
[ 002, 1 ]
[ 003, 1 ]
...
I wasn't expecting the lines with .Value being less than three.
Using .Where() instead, as explained in the answer, resolved the problem.
The SortedDictionary
is sorted on the key, not on the value, so the SkipWhile
method will not skip all items where the value is less than the minimum, it will start at the smallest key and only skip items until it finds an item where the value is larger or equal to the minimum.
If you want to filter out all items where the value is less than the minimum, use the Where
method:
lb.ItemsSource = s.Where(kvp => kvp.Value < min);
This creates an expression that reads from the SortedDictionary
as needed.
精彩评论