[英]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.