Делать несколько сортировок по нескольким строкам кода? - PullRequest
0 голосов
/ 18 августа 2011

У меня есть массив, в котором хранится порядок, по которому я хочу отсортировать список.

SortOrderArray: "Color", "Volume", "Weight"

Итак, я хочу упорядочить список по цвету, объему, а затем по весу

MyList.OrderBy(a=>a.Color).ThenBy(a=>a.Volume).ThenBy(a=>a.Weight).ToList();

Так что это довольно хорошо.Теперь я хочу написать функцию, которая выполняет эту сортировку на основе массива sortOrder, который я отправляю:

public List<row> GetSortedList(List<row> list, string[] sortOrder){
    ???
}

Я не могу понять, как это сделать без написания запроса linq для каждогокомбинация sortOrders (27 разных запросов кажутся худшим способом сделать это, и у меня довольно высокая вероятность того, что я совершу крошечную ошибку).Я хотел бы иметь возможность просто написать 3 запроса linq, которые переупорядочивают список в соответствии с каждым из 3 методов сортировки, примерно так:

switch(sortOrder[0]){
    Sort by the first sort method
}  
switch(sortOrder[1]){
    Sort by the second sort method
}
switch(sortOrder[2]){
    Sort by the third sort method
}

Но если я попытаюсь выполнить приведенный выше код, он просто перезапускаетэто каждый раз, вместо того, чтобы делать подвыборки после того, как над ним.Надеюсь, что это понятно, любая помощь будет оценена.

Ответы [ 5 ]

2 голосов
/ 18 августа 2011

Две вещи.Вам нужен метод сортировки, который выполняет «стабильную сортировку» - он сохраняет существующий порядок элементов с одинаковыми ключами.И затем вам нужно вызывать его в обратном порядке ваших критериев сортировки, чтобы первичная сортировка выполнялась последней.

0 голосов
/ 18 августа 2011

Посмотрите на этот пост от Скотта Гатри: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

0 голосов
/ 18 августа 2011

Используя Dynamic LINQ , вы можете сделать что-то вроде:

public List<row> GetSortedList(List<row> list, string[] sortOrder)
{
    // argument-validation, including testing that 
    // sort-order has at least 1 item.

    return sortOrder.Skip(1)
                    .Aggregate(list.AsQueryable().OrderBy(sortOrder.First()),
                               (query, nextSortTerm) => query.ThenBy(nextSortTerm))
                    .ToList();     
}

По существу: OrderBy первый критерий сортировки, ThenBy оставшийся.

EDIT: добавлен вызов AsQueryable, чтобы Dynamic LINQ работал на IEnumerable<T>

0 голосов
/ 18 августа 2011

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

0 голосов
/ 18 августа 2011

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

public List<row> GetSortedList(List<row> list, string[] sortOrder)
{
    IOrderedEnumerable<row> result = null;

    bool first = true;

    foreach(sortClause in sortOrder)
    {
        switch sortClause
        {
            case "Color":
                if(first)
                    result = list.OrderBy(x => x.Color);
                else
                    result = result.ThenBy(x => x.Color);
                break;
            // the other cases 
        }
        first = false;
    }    

    return result.ToList();
}

Нечто подобное.

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