繁体   English   中英

C#Array.Sort结果不一致

[英]C# Array.Sort inconsistent results

我正在尝试对制表符分隔的字符串数组进行排序。 我在每个元素的制表符上调用split函数,以将字符串分成字符串数组。 然后,我对date元素进行比较以返回它们应遵循的顺序。如果日期相等,则对字符串字段进行第二次比较。 我对IComparer接口的实现如下所示:

class CompareLines : IComparer<string>
{
    public int Compare(string x, string y)
    {
        string[] bSplitX = x.Split('\t');
        string[] bSplitY = y.Split('\t');

        int bYearX = Int32.Parse(bSplitX[4].Substring(4, 4));
        int bMonthX = Int32.Parse(bSplitX[4].Substring(0, 2));
        int bDayX = Int32.Parse(bSplitX[4].Substring(2, 2));

        int bYearY = Int32.Parse(bSplitY[4].Substring(4, 4));
        int bMonthY = Int32.Parse(bSplitY[4].Substring(0, 2));
        int bDayY = Int32.Parse(bSplitY[4].Substring(2, 2));

        DateTime bTempDateX = new DateTime(bYearX, bMonthX, bDayX);
        DateTime bTempDateY = new DateTime(bYearY, bMonthY, bDayY);

        if (DateTime.Compare(bTempDateX, bTempDateY) > 0)
        {
            return 1;
        }
        else if (DateTime.Compare(bTempDateX, bTempDateY) < 0)
        {
            return -1;
        }
        else if (DateTime.Compare(bTempDateX, bTempDateY) == 0)
        {
            if (String.Compare(bSplitX[3], bSplitY[3]) > 0)
            {
                return 1;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            Console.WriteLine("ahhh wtf"); //should never be reached. This message has never appeared in my console.
            return 0;
        }
    }
}

我的问题是,它有时可能会起作用,而不是其他人。 有谁有理由解释以上代码在100%的时间内无效?

这已经伤害了我的大脑几天了,我真的不明白为什么它不起作用。

如何更换

if (String.Compare(bSplitX[3], bSplitY[3]) > 0) {
  return 1;
} else {
  return -1;
}

return String.Compare(bSplitX[3], bSplitY[3]);

在X和Y字符串相等的情况下,您当前的代码表示Y小于X。以下是使用ParseExact方法的代码。

class CompareLines : IComparer<string>
{
    public int Compare(string x, string y)
    {
        string[] bSplitX = x.Split('\t');
        string[] bSplitY = y.Split('\t');

        DateTime bTempDateX = DateTime.ParseExact(bSplitX[4], "MMddyyyy", null);
        DateTime bTempDateY = DateTime.ParseExact(bSplitY[4], "MMddyyyy", null);

        if (DateTime.Compare(bTempDateX, bTempDateY) > 0)
            return 1;
        else if (DateTime.Compare(bTempDateX, bTempDateY) < 0)
            return -1;
        else
            return String.Compare(bSplitX[3], bSplitY[3]);
    }
}

我看到的唯一漏洞是,如果日期字符串相同,那么您将不会返回0:

        if (String.Compare(bSplitX[3], bSplitY[3]) > 0) {
            return 1;
        } else {
            return -1;  // if they are equal it will return -1.
        }

这将取消排序例程。

这是一个更干净的版本:

   int dateCompare = DateTime.Compare(bTempDateX, bTempDateY);

   if (dateCompare == 0) 
        return String.Compare(bSplitX[3], bSplitY[3]);
   else
       return dateCompare ;

首先,您不需要重写框架中内置的比较逻辑,只要您正确设置了第一手数据,它就已经返回了您期望的结果。 正如Jon所建议的那样,只需解析日期,然后返回日期的比较即可。 我添加了一个属性IncomingFormat,考虑到您的输入,该属性可能没有用。

编辑:更简洁/清晰:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;

namespace ConsoleApplication1
{
    public class CompareLines : IComparer<string>
    {
        public string IncomingFormat { get; set; }

        public int Compare(string first, string second)
        {
            var date1 = DateTime.ParseExact(first, IncomingFormat, CultureInfo.InvariantCulture);
            var date2 = DateTime.ParseExact(second, IncomingFormat, CultureInfo.InvariantCulture);

            return date1.CompareTo(date2);
        }
    }

    internal class Program
    {
        private static void Main()
        {
            const string dataFormat = "MM\tdd\tyyyy";

            var comparer = new CompareLines
            {
                IncomingFormat = dataFormat
            };

            int result;
            string date1, date2;

            date1 = DateTime.Parse("1/1/2000").ToString(dataFormat);
            date2 = DateTime.Parse("1/1/2000").ToString(dataFormat);
            result = comparer.Compare(date1, date2);
            Debug.Assert(result == 0);
            Console.WriteLine("{0} compare {1} = {2}", date1, date2, result);

            date1 = DateTime.Parse("1/1/2000").ToString(dataFormat);
            date2 = DateTime.Parse("1/2/2000").ToString(dataFormat);
            result = comparer.Compare(date1, date2);
            Debug.Assert(result == -1);
            Console.WriteLine("{0} compare {1} = {2}", date1, date2, result);

            date1 = DateTime.Parse("1/2/2000").ToString(dataFormat);
            date2 = DateTime.Parse("1/1/2000").ToString(dataFormat);
            result = comparer.Compare(date1, date2);
            Debug.Assert(result == 1);
            Console.WriteLine("{0} compare {1} = {2}", date1, date2, result);

            Console.ReadLine();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM