【问题标题】:Sorting months in a list对列表中的月份进行排序
【发布时间】:2023-03-30 13:49:02
【问题描述】:

我有一个包含一年中月份的字符串列表。我需要能够对这个列表进行排序,以便月份按月排列,而不是按字母顺序排列。我一直在寻找一段时间,但我无法理解我找到的任何解决方案。

这是一个如何添加月份的示例。它们是根据 SharePoint 列表中的字段动态添加的,因此它们可以按任何顺序排列并且可以有重复项(我将使用 Distinct() 删除它们)。

List<string> monthList = new List<string>();
monthList.Add("June");
monthList.Add("February");
monthList.Add("August");

想重新排序:

February
June
August

【问题讨论】:

  • 为什么不发回月份索引或数字?
  • 您找到了哪些解决方案?这些解决方案的哪一部分难以理解?
  • 虽然我需要我的月份名称是罗马尼亚语,但这对我很有帮助,我现在知道如何处理我的问题了!谢谢!

标签: c#


【解决方案1】:

您可以将月份名称解析为日期(假定为当前年份和第 1 天):

monthList = monthList.OrderBy(s=> DateTime.ParseExact(s, "MMMM", new CultureInfo("en-US"))).ToList();

【讨论】:

    【解决方案2】:

    您可以将字符串解析为DateTime,然后使用月份整数属性进行排序。有关支持的月份名称,请参见此处:http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.monthnames.aspx

    类似这样的:

    var sortedMonths = monthList
        .Select(x => new { Name = x, Sort = DateTime.ParseExact(x, "MMMM", CultureInfo.InvariantCulture) })
        .OrderBy(x => x.Sort.Month)
        .Select(x => x.Name)
        .ToArray();
    

    【讨论】:

    • 这对我来说实际上就像一个冠军。你介意解释一下它是如何工作的吗?这是我之前遇到的解决方案之一,但我无法理解每种方法的作用。
    • 第一个Select将对monthList中的每个项目进行操作,它将创建一个具有两个属性的新匿名类型:NameSort,其中Name是原始类型字符串,例如"January",Sort 是解析为DateTime 的字符串。然后OrderBy 可以对序列进行排序,最后将序列投影回其仅包含月份名称的原始形式。希望这有任何意义!
    • 有道理,非常感谢!
    【解决方案3】:

    您可以改用Dictionary&lt;int,string&gt;,使用int 作为月份编号进行排序,然后按键排序。

    IDictionary<int,string> monthList = new Dictionary<int,string>();
    monthList.Add(6, "June");
    monthList.Add(2, "February");
    monthList.Add(8, "August");
    
    var sorted = monthList.OrderBy(item => item.Key);
    

    【讨论】:

    • 您是否有理由使用自定义排序顺序而不是 DateTime 提供的排序顺序(解析后)?
    • @seldon - 不是真的。只是扩展 OP 所呈现的内容。根据要求,这可能就是他所需要的全部内容 - 如果他需要一个对文化敏感的排序列表(并且包含 所有 个月),那就另当别论了。
    【解决方案4】:

    如果您坚持只有一个代表月份的字符串列表,那么您必须使用另一个数据源来检索该月份的索引,您可以根据该索引对列表进行排序。例如,您可以使用月份名称作为string 键和int 索引作为值来填充字典。然后,您可以使用重载方法 List&lt;T&gt;.Sort(Comparison&lt;T&gt;) 并传入一个比较函数,该函数按名称返回月份的索引(通过将它们传递到字典中)。

    但是,我建议首先不要使用原始字符串,而是使用更结构化的数据类型来表示一个月。然后,您可以将索引嵌入数据结构本身并根据该值进行排序,从而为您提供更独立的解决方案。

    【讨论】:

    • 不,索引不需要其他数据源,至少如果您依赖将月份字符串解析为DateTime,它提供了您所说的所有丰富的数据结构.
    • @seldon:如果您像原始问题中的代码那样处理原始字符串,则需要另一个排序键。它可以是您提到的DateTime,也可以是单独的int 索引或任何合适的索引。
    • 啊,是的,你是对的。我更多地考虑自己是否定义该密钥。
    【解决方案5】:

    你需要一个 SortedList .. 比如

    SortedList<int,string> monthList=new SortedList<int,string>();
    monthList.Add(6,"June");
    monthList.Add(2,"February");
    monthList.Add(8,"August");   
    IList<string> sortedMonthList=monthList.Values;
    

    然后使用 sortedMonthList 其余部分。

    这可以通过使用 seldon 的答案来创建一个函数来改进,就像

    public static int MonthNumFromName(String monthname)
    { ... }
    

    然后使用

    monthList.Add(MonthNumFromName("June"),"June");
    

    上面。

    【讨论】:

    • 似乎@Oded 用一种稍微不同的方法击败了我
    【解决方案6】:

    好吧,我想没有任何排序技术可以将纯月份作为字符串。

    您可以只使用 Dictionary&lt;int, string&gt; 并使用 int 对您的月份进行排序。

    如果我没记错的话,你实际上有一个月份列表作为字符串,那你为什么不这样做呢?

    List<string> months = new List<string> { "January", "February", ..., "December" };
    
    var yourSortedMonthsInYourOriginalList = months.Where(m => 
                                                  originalList.Any(o => o == m)).ToList();
    

    【讨论】:

      【解决方案7】:

      您可以构建自己的排序类:

          static void Main(string[] args)
          {
              List<string> monthList = new List<string>();
              monthList.Add("June");
              monthList.Add("February");
              monthList.Add("August");
      
              monthList.Sort(new _mysort());
      
          }
      
          private class _mysort : IComparer<string>
          {
      
              public int Compare(string x, string y)
              {
                  if (x=="February" && y=="June")
                  {
                      return -1;
                  }
      
                  return 0;
              }
          }
      

      但我认为您应该使用枚举,并将其转换为字符串,然后您可以使用数字对其进行排序。

       enum months
          {
              Jan =0,
              Feb =1
          }
      

      喜欢:

             List<months> mlist = new List<months>() { months.Feb, months.Jan };
              //sort
              mlist = mlist.OrderBy(e => (int)e).ToList();
             //print
              mlist.ForEach(e => Console.WriteLine(e.ToString()));
      

      【讨论】:

        【解决方案8】:

        创建一个enum 并为每个月分配int 值。用 linq 对它进行排序。

        【讨论】:

          猜你喜欢
          • 2023-04-01
          • 2018-07-03
          • 2015-05-20
          • 1970-01-01
          • 2020-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多