2016-09-06 54 views
-2

如何讓我的Comparer考慮負數? 知道它排序我的字符串中的數字,但它留下減號(「減法」)的標誌。所以我得到了錯誤的輸出,看下面的代碼。排序字符串中的數字(數組)

public class MixedNumbersAndStringsComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     double xVal, yVal; 

     if (double.TryParse(x, out xVal) && double.TryParse(y, out yVal)) 
      return xVal.CompareTo(yVal); 
     else 
      return string.Compare(x, y); 
    } 
} 

實際輸出:

0 DAG(E)5時間(R) - XX - XX

3 DAG(E)3時間(R) - XX - XX

-4 DAG(E)-17時間(R) - XX - XX

-6 DAG(E)-18時間(R) - XX - XX

8 DAG(E)1周時間(R) - XX - XX

8 DAG(E)4時間(R) - XX - XX

預期輸出是:

- 6 DAG(E)-18時間(R) - XX - XX

-4 DAG(E)-17時間(R) - XX - XX

0 DAG(E)5時間(R) - xx - xx

3 DAG(E)3時間(R) - XX - XX

8 DAG(E)1周時間(R) - XX - XX

8 DAG(E)4時間(R) - XX - XX

輸入數據是:

TimeSpan tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration("DOMAIN", p.SamAccountName); 
TimeSpan under10 = new TimeSpan(10, 00, 00, 00); 
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00); 
if (tidtilbage < under10 && tidtilbage > ikkeMinus10) 
{ 

    if (u.Enabled == true) 
    { 
     string lines = tidtilbage.Days + " dag(e) " 
       + tidtilbage.Hours + " time(r)" + " - " 
       + p.SamAccountName.ToUpper() + " - " + p.DisplayName + "\n\n"; 

     sorted[i] = lines; 
     Array.Sort(sorted, new MixedNumbersAndStringsComparer()); 
     i++; 
    } 
} 
+0

這是有點不清楚;輸出如何與程序片斷相關並不明顯。請修改。 – Bathsheba

+0

您能否提供預期的行爲和實際的行爲?例如。預期的「-1」>「-5」,實際的「-1」<「-5」 –

+0

而且,給我們真實的輸入值。你在比較「-4」和「-17」還是「-4 dag(e)」和「-17 time(r)」? – Pikoh

回答

3

看來taht你正在尋找邏輯排序(即把字符串中整數整數"10">"9"當你排序邏輯,但"10" < "9"當你按字典順序排序)。快速而骯髒(互操作)執行:

using System.Runtime.InteropServices; 

... 

public sealed class MixedNumbersAndStringsComparer : IComparer<string> { 
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] 
    private static extern int StrCmpLogicalW(string left, string right); 

    public int Compare(string left, string right) { 
    return StrCmpLogicalW(left, right); 
    } 
} 

你甚至可以擺脫IComparer<string>

[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] 
private static extern int StrCmpLogicalW(string left, string right); 
... 

string[] data = ...; 

Array.Sort(data, (left, right) => StrCmpLogicalW(left, right)); 
+1

嗨德米特里,感謝您的答案,當我嘗試實現代碼,當前上下文中不存在SafeNativeMethods,除了使用System.Runtime.InteropServices之外,我還需要做些什麼? –

+1

@MathiasRønnowNørtoft:對於錯字我感到抱歉(我在簡化解決方案時放棄了'SafeNativeMethods'類),它應該是'return StrCmpLogicalW(left,right);' –

1

SafeNativeMethods是,你必須執行,如果你想要一個類。 在這個類中,你必須添加以下代碼:

[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)] 
static extern int StrCmpLogicalW(string x, string y); 

然而,在梅德回答的DllImport是在同一個類中已經實現。所以你不必寫「SafeNativeMethods」。

梅德的正確的代碼是:

using System.Runtime.InteropServices; 

... 

public sealed class MixedNumbersAndStringsComparer : IComparer<string> { 
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] 
    private static extern int StrCmpLogicalW(string left, string right); 

    public int Compare(string left, string right) { 
    return MixedNumbersAndStringsComparer.StrCmpLogicalW(left, right); // or return StrCmpLogicalW(left, right); 
    } 
} 

嗨。