为什么我的 linq 排序不起作用

发布于 2024-12-05 19:59:23 字数 2968 浏览 1 评论 0原文

尝试按 logtype 或按 logType 然后按 DateTime 对日志进行排序,但不起作用。我缺少什么?

      public enum LogType
    {
        Fatal,
        Error,
        Warn,
        Info,
        Debug,
        None,
    }
    public class Log
    {
        public DateTime LoggedDateTime { get; set; }
        public string Message { get; set; }
        public LogType LoggedType { get; set; }
        public override string ToString()
        {
            return string.Format("LogType: {0} Datetime: {1} Message: {2}", LoggedType, LoggedDateTime, Message);
        }
    }
    class Program
    {
        static void Main()
        {
            var logFatal = new Log
                               {
                                   LoggedDateTime = new DateTime(2011, 2, 22),
                                   Message = "Hi am a Fatal message",
                                   LoggedType = LogType.Fatal
                               };

            var logInfo = new Log
            {
                LoggedDateTime = new DateTime(2013, 2, 22),
                Message = "Hi I am a Info message",
                LoggedType = LogType.Info
            };

            var logError = new Log
            {
                LoggedDateTime = new DateTime(2010, 2, 22),
                Message = "Hi I am a Error message",
                LoggedType = LogType.Error
            };

            var logWarning = new Log
            {
                LoggedDateTime = new DateTime(2014, 2, 22),
                Message = "Hi I am a Warning message",
                LoggedType = LogType.Warn
            };
            List<Log> logs = new List<Log> { logWarning, logError, logInfo, logFatal };

            Console.WriteLine("Not Ordered");
            Console.WriteLine("");
            logs.ForEach(x=>Console.WriteLine(x.LoggedType));



            var orderedLogs = logs.OrderBy(x => x.LoggedType == LogType.Fatal)
                .ThenBy(x => x.LoggedType == LogType.Error)
                .ThenBy(x => x.LoggedType == LogType.Warn)
                .ThenBy(x => x.LoggedDateTime).ToList();

            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");
            Console.WriteLine("");

            orderedLogs.ForEach(x=>Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");//NOT WORKING
            List<Log> orderedFatal = logs.OrderBy(x => x.LoggedType == LogType.Fatal).ToList();
            orderedFatal.ForEach(x => Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Sorted by datetime AND WORKS"); //THIS IS THE ONLY ONE THAT WORKS
            logs.Sort((x,y)=>x.LoggedDateTime.CompareTo(y.LoggedDateTime));
            logs.ForEach(x => Console.WriteLine(x.LoggedDateTime));


            Console.Read();
        }
    }

感谢您的任何建议

Trying to order logs by logtype or by logType and thenBy DateTime but does not work.What am I missing?

      public enum LogType
    {
        Fatal,
        Error,
        Warn,
        Info,
        Debug,
        None,
    }
    public class Log
    {
        public DateTime LoggedDateTime { get; set; }
        public string Message { get; set; }
        public LogType LoggedType { get; set; }
        public override string ToString()
        {
            return string.Format("LogType: {0} Datetime: {1} Message: {2}", LoggedType, LoggedDateTime, Message);
        }
    }
    class Program
    {
        static void Main()
        {
            var logFatal = new Log
                               {
                                   LoggedDateTime = new DateTime(2011, 2, 22),
                                   Message = "Hi am a Fatal message",
                                   LoggedType = LogType.Fatal
                               };

            var logInfo = new Log
            {
                LoggedDateTime = new DateTime(2013, 2, 22),
                Message = "Hi I am a Info message",
                LoggedType = LogType.Info
            };

            var logError = new Log
            {
                LoggedDateTime = new DateTime(2010, 2, 22),
                Message = "Hi I am a Error message",
                LoggedType = LogType.Error
            };

            var logWarning = new Log
            {
                LoggedDateTime = new DateTime(2014, 2, 22),
                Message = "Hi I am a Warning message",
                LoggedType = LogType.Warn
            };
            List<Log> logs = new List<Log> { logWarning, logError, logInfo, logFatal };

            Console.WriteLine("Not Ordered");
            Console.WriteLine("");
            logs.ForEach(x=>Console.WriteLine(x.LoggedType));



            var orderedLogs = logs.OrderBy(x => x.LoggedType == LogType.Fatal)
                .ThenBy(x => x.LoggedType == LogType.Error)
                .ThenBy(x => x.LoggedType == LogType.Warn)
                .ThenBy(x => x.LoggedDateTime).ToList();

            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");
            Console.WriteLine("");

            orderedLogs.ForEach(x=>Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");//NOT WORKING
            List<Log> orderedFatal = logs.OrderBy(x => x.LoggedType == LogType.Fatal).ToList();
            orderedFatal.ForEach(x => Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Sorted by datetime AND WORKS"); //THIS IS THE ONLY ONE THAT WORKS
            logs.Sort((x,y)=>x.LoggedDateTime.CompareTo(y.LoggedDateTime));
            logs.ForEach(x => Console.WriteLine(x.LoggedDateTime));


            Console.Read();
        }
    }

Thanks for any suggestions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一笑百媚生 2024-12-12 19:59:24

您的 logWarninglogError 都有 LoggedType = LogType.Error

另一点:您应该实现/使用 IComparer对于 LogType...请参阅 MSDN http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx

基本上是这样的:

public class LogComparer : IComparer<Log>
{
    public int Compare(Log x, Log y)
    {
        if ( x == y ) return 0;
        if ( x.LoggedType == y.LoggedType ) return 0;
        if ( x.LoggedType == LogType.Fatal ) return 1;
        if ( y.LoggedType == LogType.Fatal ) return -1;
        // etc.
    }
}

// Usage similar to this
logs.OrderBy(x => x, new LogComparer());

Both your logWarning and logError have LoggedType = LogType.Error !

Another point: you should implement/use an IComparer for LogType... see MSDN at http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx

Bascially something like:

public class LogComparer : IComparer<Log>
{
    public int Compare(Log x, Log y)
    {
        if ( x == y ) return 0;
        if ( x.LoggedType == y.LoggedType ) return 0;
        if ( x.LoggedType == LogType.Fatal ) return 1;
        if ( y.LoggedType == LogType.Fatal ) return -1;
        // etc.
    }
}

// Usage similar to this
logs.OrderBy(x => x, new LogComparer());
淡看悲欢离合 2024-12-12 19:59:24

您可以按字段 LoggedType 对集合进行排序,然后按以下代码中的字段 LoggedDateTime 对集合进行排序:

var orderedLogs = logs.OrderBy(x => x.LoggedType) // not x => x.LoggedType == LogType.Fatal
    .ThenBy(x => x.LoggedDateTime).ToList();

我认为将会按枚举的整数表示形式进行排序。因此,您的枚举将出现致命、错误、警告等。或者您可以使用 IComparer (来自 Yahia 答案)来定义您自己的比较规则。

You can sort the collection by the field LoggedType, then by the field LoggedDateTime in the following code:

var orderedLogs = logs.OrderBy(x => x.LoggedType) // not x => x.LoggedType == LogType.Fatal
    .ThenBy(x => x.LoggedDateTime).ToList();

I think there will be sorting by integer representation of enum. So with your enum there will be Fatal, Error, Warn etc. Or you can use IComparer (from Yahia answer) for your own definition rules of comparison.

○闲身 2024-12-12 19:59:24

你需要做类似的事情:

var orderedLogs = logs.GroupBy(l => l.LoggedType)
                    .OrderBy(g => g.Key)
                    .SelectMany(g => g.OrderByDescending(l => l.LoggedDateTime)).ToList();

You need to do something like:

var orderedLogs = logs.GroupBy(l => l.LoggedType)
                    .OrderBy(g => g.Key)
                    .SelectMany(g => g.OrderByDescending(l => l.LoggedDateTime)).ToList();
你爱我像她 2024-12-12 19:59:23

问题是 false 排在 true 之前。
因此,按照您的顺序,首先是那些非致命的。首先出现的不是错误等。

您可以使用不等式使其发挥作用:

x => x.LoggedType != LogType.Fatal

等等

,或使用OrderByDescendingThenByDescending

但我更愿意给出枚举的顺序:

public enum LogType : int
    {
        Fatal = 5,
        Error = 4,
        Warn = 3,
        Info = 2,
        Debug = 1,
        None = 0,
}

然后只使用这个值:

var orderedLogs = logs.OrderByDescending(x => x.LoggedType);

The problem is that false is ordered before true.
Thus first in your order come those that are not Fatal. Out of those first come those that are not Error etc.

You can use inequalities to make it work:

x => x.LoggedType != LogType.Fatal

etc.

or use OrderByDescending and ThenByDescending.

But I'd prefer to give an order of the enum:

public enum LogType : int
    {
        Fatal = 5,
        Error = 4,
        Warn = 3,
        Info = 2,
        Debug = 1,
        None = 0,
}

and then just use this value:

var orderedLogs = logs.OrderByDescending(x => x.LoggedType);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文