English 中文(简体)
achieving a complex sort via Linq to Objects
原标题:

I ve been asked to apply conditional sorting to a data set and I m trying to figure out how to achieve this via LINQ. In this particular domain, purchase orders can be marked as primary or secondary. The exact mechanism used to determine primary/secondary status is rather complex and not germane to the problem at hand.

Consider the data set below.

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 

Secondary POs are those with a decimal number and primary PO s are those with an integer number. The requirement I m dealing with stipulates that when a user chooses to sort on a given column, the sort should only be applied to primary POs. Secondary POs are ignored for the purposes of sorting, but should still be listed below their primary PO in ship date descending order.

For example, let s say a user sorts on Shipping Address ascending. The data would be sorted as follows. Notice that if you ignore the secondary POs, the data is sorted by Address ascending (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 

Is there a way to achieve the desired effect using the OrderBy extension method? Or am I stuck (better off) applying the sort to the two data sets independently and then merging into a single result set?

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
}
最佳回答

The solution for your problem is GroupBy.

First order your object according to selected column:

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

Than you need to group your orders according to the primary order. I assumed the order is a string, so i created a string IEqualityComparer like so:

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();
    }
}

and use it to group the orders:

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

The result is a tree like structure ordered by the ShippingAddress column and grouped by the primary order id.

问题回答

Have you seen ThenBy and ThenByDescending methods?

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

I m not sure if this is going to fit your needs because I don t quiet understand well how final list should look like (po.IsPrimary and !po.IsPrimary is confusing me).





相关问题
How do I sort enum members alphabetically in Java?

I have an enum class like the following: public enum Letter { OMEGA_LETTER("Omega"), GAMMA_LETTER("Gamma"), BETA_LETTER("Beta"), ALPHA_LETTER("Alpha"), private final String ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Sorting twodimensional Array in AS3

So, i have a two-dimensional Array of ID s and vote count - voteArray[i][0] = ID, voteArray[i][1] = vote count I want the top 3 voted items to be displayed in different colors, so i have a 2nd Array -...

Linq operations against a List of Hashtables?

I m working with a set of legacy DAO code that returns an IList, where each Hashtable represents the row of a dynamically executed SQL query. For example, the List might contain the following records/...

C++ Array Sort Me

Stuck on an array sorter. Have to sort numbers from largest to smallest. I m trying two loops (one nested in the other). Here s the code: int counter=0; // inner counter int counter2=0; // outer ...

Can I Nest OrderBy in .NET?

This doesn t seem to work as I intend. VB.NET: Dim x = Model.Discussions.OrderByDescending(Function(d) d.Messages.OrderByDescending(Function(m) m.Sent).First.Sent) For Each d As Discussion In x ....

sorting elements javascript

I m looking for a way to sort my elements, but it isn t as easy as it sounds. Please let me explain My elements are grouped per 6 elements (thumbnails), each x represents a thumbnail However all ...

热门标签