2016-09-06 2 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 даг (е) 5 раз (г) - хх - хх

3 даг (е) 3 раз (г) - хх - хх

-4 даг (е) -17 раз (г) - хх - хх

-6 даг (е) -18 раз (г) - хх - хх

8 даг (е) 1 раз (г) - хх - хх

8 даг (е) 4 раз (г) - хх - хх

ожидается выход:

- 6 даг (е) -18 раз (г) - хх - хх

-4 даг (е) -17 раз (г) - хх - хх

0 даг (е) 5 раз (г) - xx - xx

3 даг (е) 3 раз (г) - хх - хх

8 даг (е) 1 раз (г) - хх - хх

8 даг (е) 4 раз (г) - хх - хх

входные данные:

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" при сортировке лексически). Быстрая и грязная (Interop) реализация:

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

@ Mathias Rønnow Nørtoft: Мне жаль, что опечатка (я отказался от класса SafeNativeMethods' при упрощении моего решения), это должно быть 'return StrCmpLogicalW (слева, справа);' –

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); 
    } 
} 

Привет.