C# 将C列表拆分为两个

C# 将C列表拆分为两个,c#,asp.net,generics,list,C#,Asp.net,Generics,List,我正在使用C和ASP.NET3.5。基本上,我从数据集中检索一列数据,并将其放入如下列表: List<String> dates = new List<String>(); foreach (DataRow rowMonth in myDS.Tables[0].Rows) { string ListedMonthYear = (string)rowMonth[0]; dates.Add(ListedMonthYea

我正在使用C和ASP.NET3.5。基本上,我从数据集中检索一列数据,并将其放入如下列表:

    List<String> dates = new List<String>();

    foreach (DataRow rowMonth in myDS.Tables[0].Rows)
    {
        string ListedMonthYear = (string)rowMonth[0];
        dates.Add(ListedMonthYear);
    }
我感兴趣的是将这些值分成两个列表,以便将来对它们执行操作

Apr   |  2010
Mar   |  2010
Feb   |  2010
Jan   |  2010
Dec   |  2009
Nov   |  2009
Oct   |  2009
最好的方法是什么

编辑:rowMonth只是包含所有日期相关值的数据行—月份年份、月初、月底、月活动或非活动。基本上,我只是试图提取第一列月份,然后对其进行操作,而忽略其余部分。

您可以使用LINQ:

var months = (from item in dates
              select item.Substring(0, 3))
             .ToList();

var years  = (from item in dates
              select 2000 + int.Parse(item.Substring(4, 2)))
             .ToList();
您可能更愿意将这两个部分分别存储在同一个列表中:

var result = (from item in dates
              select Tuple.Create(item.Substring(0, 3),
                                  2000 + int.Parse(item.Substring(4, 2))))
             .ToList();

如果日期仅在2000年之后,则可以执行以下操作:

dates.Select(d => d.Split('-')).Select(parts => new { Month = parts[0], Year = "20"+parts[0]})

这样,您就不会在列表上重复两次。但它只适用于2k年及以上,我假设您希望将年作为整数列表

List<string> months = new List<string>();
List<int> years = new List<int>();


dates.ForEach(s =>
            {
                months.Add(s.Substring(0, 3));
                years.Add(2000 + int.Parse(s.Substring(4, 2)));
            });

我会考虑使用DATETION对象而不是字符串,这样您就可以立即获得日期/时间表示,而不必维护两个列表。

例如,可以将原始解析方法更改为以下内容

List<DateTime> dates = new List<DateTime>();

foreach (DataRow rowMonth in myDS.Tables[0].Rows)
{
    DateTime rowDate = DateTime.Parse(rowMonth[0]);
    dates.Add(rowDate);
}
然后,要生成两个必需的列表,可以使用linq,如下所示

// Converting to lists to demonstrate, though may not be required in your app.
List<short> years = dates.Select(d => d.Year).ToList();
List<string> months = dates.Select(d =>
    CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(d.Month)).ToList();
注意这并不是你想要的,因为有一些小的警告

如果行中的日期不是已知的日期格式,则可能需要使用格式字符串定制DateTime.Parse。 GetMonthName返回完整的月份名称;您可以破解一个解决方案来获取字符串的前三个字符,但可能有一个更优雅的解决方案。
rowMonth[0]的类型是什么?@Andrey:显然有些东西可以转换成字符串。@dtb是的,但如果是日期时间,首先将其转换成字符串是一种巨大的浪费,如果不是日期时间,则应该如此。@dtb Joel解释了我问题背后的内容是的,这不是日期时间,这更多的是从db返回的数据集中的nvarchar数据。那时我已经离开很久了,所以这不是我的问题!!我想如果我写的任何代码都能持续到2100年,我将是一个传奇人物,日期时间问题将不会成为问题。是的,那是他们在1965年说的。我当然希望我不必再支持这个应用程序90年。ToList只是为了ForEach?伙计@dtb我的印象是,基准测试使它比foreach循环快得多。+1这是性能更好的代码,尽管我们没有迹象表明列表是否会变得非常大。@Yuriy Faktorovich:enumerable.ToList.foreach在enumerable中比foreach var x快?有趣的Link?@dtb:我已经完成了基准测试,我目前的版本是最快的。它结合了我们的两个答案。我在寻找ToList.ForEach和ForEach的基准。我想你指的是item.Substring0,3@Yuriy法克托洛维奇:的确。谢谢。我认为元组可能是2010年的功能——2008年有类似的功能吗?@firedrawndagger:没有,但您可以轻松定义自己的类,其中包含一个字符串和一个整数。+1。如果此项目可以使用DateTimes而不是字符串,请执行此操作。它更有意义,并且更容易获得单个时间组件,而不必依赖于创建子字符串。
// Converting to lists to demonstrate, though may not be required in your app.
List<short> years = dates.Select(d => d.Year).ToList();
List<string> months = dates.Select(d =>
    CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(d.Month)).ToList();