Как использовать List.Sort и Comparision (of T) для сортировки Descensing / Ascending? - PullRequest
2 голосов
/ 05 июля 2011

у меня есть MyObject; myObjects as List(Of MyObject) и делегат Comparison(Of MyObject), который использует множество функций сравнения (ByA, ByB, ByC и т. Д.) À la:

Shared Function CompareMyObjectsByName(x As MyObject, y As MyObject) As Integer
    Return x.Name.CompareTo(y.Name)
End Function

Теперь я могу использовать

myObjects.Sort(AddressOf CompareMyObjectsByName)

Как я могу использовать это для сортировки По убыванию или По возрастанию ?

а-ля

myObjects.Sort(AddressOf CompareMyObjectsByName, ascending)

PS. Не говорите, что я должен написать 2 разных компаратора ...

EDIT @ Джон Скит

  ''' <summary>
  ''' Sorts a list ascensing or descending using a comparison delegate.
  ''' </summary>
  <System.Runtime.CompilerServices.Extension()> _
  Public Sub Sort(Of T)(ByVal list As List(Of T), ByVal comparison As Comparison(Of T), ByVal descending As Boolean)

    If Not descending Then
      list.Sort(comparison)
    Else
      list.Sort(???)
    End If

  End Sub

Ответы [ 2 ]

4 голосов
/ 05 июля 2011

Самый простой способ - создать ReverseComparer(Of T), который можно построить из существующего IComparer(Of T), и отменить сравнение. (Просто вызовите существующее сравнение с обратным порядком аргументов - не не отменяйте результат вместо этого; это не удается для Int32.MinValue.) У меня есть такой класс в C # уже в MiscUtil , если тебе интересно.

Тогда вам просто нужно отсортировать, передавая восходящий компаратор или создав обратный компаратор из восходящего.

РЕДАКТИРОВАТЬ: Как представляется, я не проясняю себя, я имею в виду метод расширения - написанный на C #, но должно быть легко преобразовать его в VB:

public static void Sort<T>(this List<T> list,
                           IComparer<T> comparer,
                           bool ascending)
{
    if (!ascending)
    {
        comparer = new ReverseComparer<T>(comparer);
    }
    list.Sort(comparer);
}

или для Comparison<T>:

public static void Sort<T>(this List<T> list,
                           Comparison<T> comparison,
                           bool ascending)
{
    if (!ascending)
    {
        // Avoid capturing the variable we're modifying!
        Comparison<T> originalComparison = comparison;
        comparison = (x, y) => originalComparison(y, x);
    }
    list.Sort(comparison);
}

Конечно, я бы обычно использовал OrderBy и OrderByDescending, если вам действительно не нужно изменять исходный список ...

РЕДАКТИРОВАТЬ: Дальнейшее примечание: как предложено Конрадом, вы можете захотеть перечислить с членами Ascending и Descending вместо флага bool, просто для ясности.

1 голос
/ 05 июля 2011

Принимая предложение Джона, но заставляя его работать с лямбда-выражением:

myObjects.Sort(Function (a, b) CompareMyObjectsByName(b, a))

- нет необходимости создавать новый метод для каждой логики сравнения;просто вызовите соответствующий метод сравнения внутри лямбды с обратными аргументами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...