Алгоритм сортировки CollectionViewSource

1

Как изменить алгоритм сортировки CollectionViewSource? Фактически, я обнаружил, что алгоритм сортировки CollectionViewSource нестабилен. И я хочу использовать стабильный алгоритм для CollectionViewSource. Как я могу это сделать?

Теги:
sorting
collectionviewsource

2 ответа

3
Лучший ответ

Мне удалось получить стабильную сортировку, используя пользовательский Comparer, но это похоже на большой взлом...

Так же, как предложил Бенджамин, я получаю ListCollectionView из коллекции и устанавливаю его свойство CustomSort своим пользовательским Comparer. Единственное отличие состоит в том, что я передаю коллекцию в Comparer при ее создании.

private void Sorting(IEnumerable collection)
{
    var view = CollectionViewSource.GetDefaultView(collection) as ListCollectionView;

    if (view != null)
    {
        view.CustomSort = new StableComparer(collection);
    }
}

Затем, в моем обычном Comparer, я использую коллекцию в методе Compare только для возврата к индексам элементов, когда сравнение возвращает ноль (они одинаковы или имеют одинаковое значение).

public class StableComparer : IComparer
{
    public IEnumerable Collection { get; set; }

    public StableComparer(IEnumerable collection)
    {
        Collection = collection;
    }

    public int Compare(object x, object y)
    {
        IComparable x_Comparable = x as IComparable;
        IComparable y_Comparable = y as IComparable;

        if (x_Comparable != null && y_Comparable != null)
        {
            var comparison = x_Comparable.CompareTo(y_Comparable);

            // A zero value means x and y are equivalent for sorting, and they could
            //  be rearranged by an unstable sorting algorithm
            if (comparison == 0 && Collection != null)
            {
                // IndexOf is an extension method for IEnumerable (not included)
                var x_Index = Collection.IndexOf(x);
                var y_Index = Collection.IndexOf(y);

                // By comparing their indexes in the original collection, we get to
                //  preserve their relative order
                if (x_Index != -1 && y_Index != -1)
                    comparison = x_Index.CompareTo(y_Index);
            }

            return comparison;
        }

        return 0;
    }
}

Я все еще проверяю это, поэтому я не могу гарантировать, что это будет работать все время... Одна проблема заключается в том, что сохранение свойства Collection внутри Comparer обновляется, например. Или поддерживает два направления сортировки.

Но я думаю, что идея ясна, хотя и взломана, как я уже сказал.

2

Вы можете проверить, как реализовать свою собственную логику сортировки.

Короче говоря, установите свой компаратор следующим образом:

private void Sort(object sender, RoutedEventArgs args)
{
    BlogPosts posts = (BlogPosts)(this.Resources["posts"]);
    ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(posts));
    lcv.CustomSort = new SortPosts();
}

И реализуйте его вот так:

public class SortPosts : IComparer
{
    public int Compare(object x, object y)
    {
        (…)
    }
}
  • 0
    этот случай просто установить новый способ сравнения между двумя объектами. Но может ли это изменить стабильность алгоритма сортировки?
  • 0
    Это зависит от того, как вы реализуете свой IComparer .
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню