C# Linq SortedList筛选到SortedList

8

我有一些代码,其中我正在进行某些奇怪的操作,以从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);

有什么想法可以让这个更简洁明了(俗话说得好,少即是多)?
谢谢,
乔纳森
2个回答

11

你可以移除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);

...但是这将会构建一个中间的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;
}

那么调用代码就会变成这样:

var mostDays = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved)
                      .ToSortedList(x => x.Key, x => x.Value);

我认为这应该是相当高效的,因为它在构建期间总是将值添加到列表的末尾

(如果要完整地完成工作,您需要添加接受自定义键比较器等的重载...请参见ToDictionary。)


这就是我喜欢这个网站的原因。快速有效的答案让我感觉到自己学到了重要的东西。谢谢Jon。 - Jonathan

2

这并不是对你问题的直接回答(抱歉!)- 更多是关于问题本身的疑问:

  • 你实际上需要输出为 SortedList 吗?
  • 或者你能否使用一个 IEnumerable 作为输出,只要结果顺序正确就行了?

如果你在创建 mostDays 集合之后,永远不打算再添加/插入更多项,那么你可以显然地使用 var mostDays = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved); 创建一个 IEnumerable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接