достижение сложной сортировки через Linq to Objects - PullRequest
1 голос
/ 16 ноября 2009

Меня попросили применить условную сортировку к набору данных, и я пытаюсь выяснить, как этого добиться с помощью LINQ. В этом конкретном домене заказы на покупку могут быть помечены как первичные или вторичные. Точный механизм, используемый для определения первичного / вторичного статуса, довольно сложен и не имеет отношения к рассматриваемой проблеме.

Рассмотрим данные, приведенные ниже.

Purchase Order    Ship Date       Shipping Address     Total
6                  1/16/2006       Tallahassee FL      500.45 
19.1             2/25/2006       Milwaukee WI        255.69 
5.1              4/11/2006       Chicago IL          199.99 
8                  5/16/2006       Fresno CA           458.22 
19                7/3/2006        Seattle WA          151.55
5                   5/1/2006        Avery UT            788.52    
5.2                 8/22/2006       Rice Lake MO        655.00 

Вторичные PO - это те, которые имеют десятичное число, а первичные PO - это целые числа. Требование, с которым я имею дело, предусматривает, что когда пользователь выбирает сортировку по заданному столбцу, сортировка должна only применяться к первичным PO. Вторичные PO игнорируются для целей сортировки, но все равно должны быть перечислены ниже их первичного PO в порядке убывания даты отгрузки.

Например, скажем, пользователь сортирует по адресу доставки по возрастанию. Данные будут отсортированы следующим образом. Обратите внимание, что если вы игнорируете вторичные PO, данные сортируются по возрастанию адреса (Avery, Фресно, Сиэтл, Таллахасси)

Purchase Order      Ship Date       Shipping Address     Total
5                   5/1/2006        Avery UT            788.52  
--5.2               8/22/2006       Rice Lake MO        655.00  
--5.1                4/11/2006       Chicago IL          199.99 
8                   5/16/2006       Fresno CA           458.22 
19                  7/3/2006        Seattle WA          151.55
--19.1               2/25/2006       Milwaukee WI        255.69 
6                   1/16/2006       Tallahassee FL      500.45 

Есть ли способ достичь желаемого эффекта с помощью метода расширения OrderBy? Или я застрял (лучше) применить сортировку к двум наборам данных независимо, а затем слить в один результирующий набор?

public IList<PurchaseOrder> ApplySort(bool sortAsc)
{
    var primary = purchaseOrders.Where(po => po.IsPrimary)
                                .OrderBy(po => po.ShippingAddress).ToList();
    var secondary = purchaseOrders.Where(po => !po.IsPrimary)
                                  .OrderByDescending(po => po.ShipDate).ToList();
    //merge 2 lists somehow so that secondary POs are inserted after their primary
}

Ответы [ 2 ]

3 голосов
/ 16 ноября 2009

Видели ли вы методы ThenBy и ThenByDescending?

purchaseOrders.Where(po => po.IsPrimary).OrderBy(po => po.ShippingAddress).ThenByDescending(x=>x.ShipDate).ToList();

Я не уверен, что это будет соответствовать вашим потребностям, потому что я не совсем понимаю, как должен выглядеть окончательный список (po.IsPrimary и! Po.IsPrimary сбивают меня с толку).

2 голосов
/ 16 ноября 2009

Решением вашей проблемы является GroupBy.

Сначала упорядочите ваш объект согласно выбранному столбцу:

var ordered = purchaseOrders.OrderBy(po => po.ShippingAddress);

Чем вам нужно сгруппировать ваши заказы в соответствии с основным заказом. Я предположил, что заказ является строкой, поэтому я создал строку IEqualityComparer примерно так:

class OrderComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        x = x.Contains('.') ? x.Substring(0, x.IndexOf('.')) : x;
        y = y.Contains('.') ? y.Substring(0, y.IndexOf('.')) : y;

        return x.Equals(y);
    }

    public int GetHashCode(string obj)
    {
        return obj.Contains('.') ? obj.Substring(0, obj.IndexOf('.')).GetHashCode() : obj.GetHashCode();
    }
}

и использовать его для группировки заказов:

var grouped = ordered.GroupBy(po => po.Order, new OrderComparer());

Результатом является древовидная структура, упорядоченная по столбцу ShippingAddress и сгруппированная по первичному идентификатору заказа.

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