1

データセットに条件付き並べ替えを適用するように求められましたが、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は10進数のPOであり、プライマリPOは整数のPOです。私が扱っている要件では、ユーザーが特定の列で並べ替えを選択した場合、並べ替えはプライマリPOにのみ適用する必要があると規定されています。セカンダリPOは並べ替えの目的で無視されますが、出荷日の降順でプライマリPOの下に表示される必要があります。

たとえば、ユーザーが配送先住所を昇順で並べ替えるとします。データは次のように並べ替えられます。セカンダリPOを無視すると、データはアドレスの昇順(Avery、Fresno、Seattle、Tallahassee)で並べ替えられることに注意してください。

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拡張メソッドを使用して目的の効果を達成する方法はありますか?または、2つのデータセットに個別に並べ替えを適用してから、単一の結果セットにマージすることに固執していますか?

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
}
4

2 に答える 2

3

ThenByメソッドとThenByDescendingメソッドを見たことがありますか?

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

最終的なリストがどのように表示されるかをよく理解していないため、これがあなたのニーズに合うかどうかはわかりません(po.IsPrimaryと!po.IsPrimaryは私を混乱させます)。

于 2009-11-16T15:45:22.450 に答える
2

あなたの問題の解決策はです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列で順序付けられ、プライマリ注文IDでグループ化されたツリーのような構造になります。

于 2009-11-16T16:48:14.557 に答える