【问题标题】:C# - Sort dictionary based on Modified date and created dateC# - 根据修改日期和创建日期对字典进行排序
【发布时间】:2013-05-02 07:21:19
【问题描述】:

我在字典中有一些记录,我需要根据创建日期 (CDate) 和修改日期 (MDate) 对数据进行排序。创建记录时,我的 CDate 将具有当前日期时间,但 MDate 将是 1/1/0001 12:00:00 AM。

这是用于排序的示例数据和代码。

CDate MDate
2013 年 4 月 30 日下午 4:43:41 2013 年 4 月 30 日下午 4:46:47
2013 年 4 月 30 日下午 4:43:28 2013 年 4 月 30 日下午 4:46:36
2013 年 4 月 30 日下午 4:43:54 2013 年 4 月 30 日下午 4:46:16
2013 年 4 月 30 日下午 5:03:13 0001 年 1 月 1 日上午 12:00:00

代码:

FileSchedulerEntities = FileSchedulerEntities
                       .OrderByDescending(pair => pair.Value.MDate)
                       .ThenByDescending(pair => pair.Value.CDate)
                       .ToDictionary(pair => pair.Key, pair => pair.Value);

按照排序,我需要像这样按降序对数据进行排序。
CDate MDate
2013 年 4 月 30 日下午 5:03:13 0001 年 1 月 1 日上午 12:00:00
2013 年 4 月 30 日下午 4:43:41 2013 年 4 月 30 日下午 4:46:47
2013 年 4 月 30 日下午 4:43:28 2013 年 4 月 30 日下午 4:46:36
2013 年 4 月 30 日下午 4:43:54 2013 年 4 月 30 日下午 4:46:16

但上述代码不起作用。有什么想法吗?

【问题讨论】:

  • 我认为您无法对字典进行排序。你为什么不玩玩List<KeyValuePair<string, string>>
  • @naveen - 如果字典不可排序,那么 OrderByDescending() 和 ThenByDescending() 有什么优势?
  • @MidhunlalG:请参阅我的回答的长评论。它回答了这个问题。

标签: c# linq dictionary


【解决方案1】:

根据the documentation,字典中的项目顺序未定义:

项目返回的顺序是不确定的。

如果您需要一个允许通过密钥进行 O(1) 访问的结构,请使用 Dictionary<TKey, TValue>
如果您需要有序结构,请使用 List<KeyValuePair<TKey, TValue>> 之类的内容。

【讨论】:

  • 但我正在手动对数据进行排序。但是排序没有按预期工作。
  • @MidhunlalG:因为在排序之后,您将数据存储回字典中,实际上丢失了您刚刚执行的所有排序。
  • 如果字典不可排序,那么 OrderByDescending() & ThenByDescending() 有什么好处呢?
  • 我也尝试使用此代码,但没有存储回字典。 FileSchedulerEntities .OrderByDescending(pair => pair.Value.MDate) .ThenByDescending(pair => pair.Value.CDate);。但没有运气。
  • @MidhunlalG: OrderBy 和类似命名的方法是IEnumerable<T> 上的扩展方法Dictionary<TKey, TValue> 实现 IEnumerable<KeyValuePair<TKey, TValue>>。这就是为什么这些扩展方法可以在字典中使用的原因。调用它们将产生一个IEnumerable<KeyValuePair<TKey, TValue>>,它按照您指定的方式排序。所以他们在这里是有道理的。你的错误是调用ToDictionary()。这将从排序的枚举中创建一个字典。但这种转换不是无损的,因为(续)
【解决方案2】:

试试SortedDictionary

您可以创建自己的 ToSortedDictionary

public static SortedDictionary<TKey, TElement> ToSortedDictionary<TSource, TKey, TElement>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    Func<TSource, TElement> elementSelector,
    IEqualityComparer<TKey> comparer)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }

    if (keySelector == null)
    {
        throw Error.ArgumentNull("keySelector");
    }

    if (elementSelector == null)
    {
        throw Error.ArgumentNull("elementSelector");
    }

    var dictionary = new SortedDictionary<TKey, TElement>(comparer);
    foreach (TSource local in source)
    {
        dictionary.Add(keySelector(local), elementSelector(local));
    }

    return dictionary;
}

【讨论】:

  • 这个答案错过了一个关键点:这不会保留OrderBy 等人创建的排序。它会按照比较器认为正确的顺序进行排序。
  • 它是您正在寻找的更专业的字典,您需要自己实现它。
  • 我认为问题是关于 ToDictionary 返回的字典未按您想要的顺序排序。由于它是设计的方式,因此您现在确定您必须自己实现它。还是现在的问题是“如何实施?”如果是这样,我们需要了解您的要求以提供帮助。您需要对值进行排序还是需要对键进行排序?
  • 保罗,我不是问这个问题的人。我是提供已接受答案的人。
  • @DanielHilgarth,哎呀!我的错!
猜你喜欢
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多