我想在.NET中对此列表进行排序,我的示例代码如下

时间:2011-11-02 13:06:08

标签: .net linq sql-order-by

class Program
{


    static void Main(string[] args)
    {

        //Period 01 2008, Period 02 2008
        Series s1 = new Series { Text = "Period 01 2008", Value = "1"};
        Series s2 = new Series { Text = "Period 02 2008", Value = "2" };
        Series s3 = new Series { Text = "Period 03 2008", Value = "3" };

        Series s11 = new Series { Text = "Period 01 2009", Value = "1" };
        Series s21 = new Series { Text = "Period 02 2009", Value = "2" };
        Series s31 = new Series { Text = "Period 03 2009", Value = "3" };

        Series s12 = new Series { Text = "Period 01 2010", Value = "1" };
        Series s22 = new Series { Text = "Period 02 2010", Value = "2" };
        Series s32 = new Series { Text = "Period 03 2010", Value = "3" };

        List<Series> series = new List<Series> { s21, s31, s1, s12, s11, s2, s22, s3, s32 };


       // mySeries.ForEach(i => Console.WriteLine("Period {0} {1}",i.Period, i.Year));
        series.ForEach(i => Console.WriteLine(i.Text));

        Console.WriteLine("************************");

        series.OrderBy(i => i.Text);

        series.ForEach(i=> Console.WriteLine(i.Text));

    }

}


public class Series
{
    public string Text { get; set; }
    public string Value {get;set;}
}

基本上我希望我的列表由Text类的Series属性排序。我通过拆分文本进行解决方法,但我正在寻找其他任何方式 - 使用IComparer可能吗?

有序列表应该是这样的:

  

2008年第01期,2008年第02期,2008年第03期,2009年第01期,   2009年02期...

更新:无法更改Series类的定义。

5 个答案:

答案 0 :(得分:2)

LINQ OrderBy扩展方法返回一个新的排序序列,你没有做任何事情。
它不会修改原始列表。

相反,您可以调用List<T>.Sort,这是一个改变List<T>实例的就地排序:

series.Sort((a, b) => a.Text.CompareTo(b.Text));

答案 1 :(得分:0)

将main方法中的倒数第二行更新为:

series = series.OrderBy(i => i.Text).ToList();

快乐编码

答案 2 :(得分:0)

我会添加DateTime属性

Series s1 = new Series { 
    Text = "Period 01 2008", 
    Value = "1", 
    PeriodStart = new DateTime(2008, 01, 01) 
};

并按顺序排序:

series.OrderBy(i => i.PeriodStart).ForEach(i => Console.WriteLine(i.Text));

所以你不能把所有的Januaries放在一起。

此外,Text属性的任何更改都不会影响您的排序,这些更改用于显示目的。

答案 3 :(得分:0)

虽然我不会自己这样做,但这有效:

var sorted = series.OrderBy(s => s.Text.Split(' ')[2].Trim()).ThenBy(s => s.Text.Split(' ')[1].Trim());

这演示了进行排序所需的LINQ类型。我在这里没有这样做,但你需要在null /缺少字符串部分时更加防守。

<强>替代地

解决问题的一种稍微不同的方法是包装Series类并公开更多有用的属性(免责声明,需要更好的解析代码!):

class BetterSeries
{
    public int Quarter {get;set;}
    public int Year {get;set;}
    public Series InnerSeries {get;private set;}

    public BetterSeries(Series s)
    {
        string[] parts = s.Text.Split(' ');
        Quarter = int.Parse(parts[1].Trim());
        Year = int.Parse(parts[2].Trim());
        InnerSeries = s;
    }

    public override string ToString()
    {
        return string.Format("Period {0} {1}", Quarter, Year);
    }
}

这样可以让您更简单地进行排序:

var sorted = series.OrderBy(s => s.Year).ThenBy(s => s.Quarter);

这也意味着您没有将信息编码到数据的格式化输出中,您存储数据本身,然后添加代码以格式化输出。

答案 4 :(得分:0)

添加以下比较器

public class SeriesTextComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        string[] xparts = x.Split(' ');
        string[] yparts = y.Split(' ');

        if (xparts[2] == yparts[2])
        {
            if (Convert.ToInt32(xparts[1]) > Convert.ToInt32(yparts[1]))
            {
                return 1;
            }
            else if(Convert.ToInt32(xparts[1]) < Convert.ToInt32(yparts[1]))
            { 
                return -1;
            }
            else
            {
                return 0;
            }
        }
        else
        { 
        if (Convert.ToInt32(xparts[2]) > Convert.ToInt32(yparts[2]))
            {
                return 1;
            }
            else if(Convert.ToInt32(xparts[2]) < Convert.ToInt32(yparts[2]))
            { 
                return -1;
            }
            else
            {
                return 0;
            }
        }
    }
}

并更改示例中的最后两行

List<Series> sortedSeries =  series.OrderBy(i => i.Text, new SeriesTextComparer()).ToList();
sortedSeries.ForEach(i => Console.WriteLine(i.Text));