C#Linq SortedList过滤到SortedList

Jon*_*han 5 c# linq filter sortedlist

我有一些代码,我正在做一些奇怪的事情,从SortedList获取信息,然后回到另一个SortedList.我做了我的where子句,然后必须单独将所有KeyValuePairs放回到新的SortedList中.

不是最有效,或者确实是推荐的方式,但我似乎无法找到更好的方法.

这是代码:

SortedList<DateTime, CalendarDay> most_days = 
                                new SortedList<DateTime, CalendarDay>();
List<KeyValuePair<DateTime, CalendarDay>> days = this.all_days.Where (
                                  n => n.Value.IsRequested || n.Value.IsApproved
                                  ).ToList();
foreach (KeyValuePair<DateTime, CalendarDay> kvp in days)
    most_days.Add(kvp.Key, kvp.Value);
Run Code Online (Sandbox Code Playgroud)

关于如何清理它的任何想法(正如他们所说,少即是多)?

谢谢,

乔纳森

Jon*_*eet 9

嗯,你当然可以删除ToList电话 - 这根本没有帮助你.

您可以使调用代码更简单:

var dictionary = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved)
                        .ToDictionary(x => x.Key, x => x.Value);
var mostDays = new SortedList<DateTime, CalendarDay>(dictionary);
Run Code Online (Sandbox Code Playgroud)

......但那将构建一个中级Dictionary<,>,所以它几乎没有效率.

另一种选择是您可以编写自己的ToSortedList扩展方法,例如

public static SortedList<TKey, TValue> ToSortedList<TSource, TKey, TValue>
    (this IEnumerable<TSource> source,
     Func<TSource, TKey> keySelector,
     Func<TSource, TValue> valueSelector)
{
    // TODO: Argument validation
    var ret = new SortedList<TKey, TValue>();
    foreach (var element in source)
    {
        ret.Add(keySelector(element), valueSelector(element));
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

然后调用代码将是:

var mostDays = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved)
                      .ToSortedList(x => x.Key, x => x.Value);
Run Code Online (Sandbox Code Playgroud)

我怀疑这应该是合理有效的,因为它总是会在构造期间将值添加到列表的末尾.

(对于完整的工作,您需要添加接受自定义键比较器等的重载...请参阅ToDictionary.)