mark smith
mark smith

Reputation: 20907

Sorting an List<> with my custom order which is stored in another List (C#)?

Can anyone help.. I have a generic list like so

    IList<itemTp> itemTps;

itemTp basically is a class (has a number of properties) and one property on this is "code"

I need to be able to sort it an specific order which i have set in another List.

This list is a simple list that lists the order (starting from first to last) like say

code1 code3 code2 code5 (notice it goes from 1 to 3 to 2 to 5 - these are the names, they can be called anything .. the important thing is the order, it doesn't have anything to do with the numbers)

Basically i need ensure the items in itemTp sort according what is present in the other list...

So imagine my Ilist is like this code1,code2,code3,code5 - so once the sort is done in my

       IList<itemTp>

will contain 4 classes that are in order and have the property like code1,code3,code2,code5 (order change)

Any ideas how to do this?

Upvotes: 7

Views: 3890

Answers (3)

Per Erik Stendahl
Per Erik Stendahl

Reputation: 883

Using C# 3 and LINQ to Objects, I would just create a new list instead of trying to sort the existing one:

void Example()
{
    IList<string> codes;
    IList<ItemTp> itemTps;
    itemTps = codes.Select(code => itemTps.Single(itp => itp.Code == code)).ToList();
}

Upvotes: 0

vgru
vgru

Reputation: 51292

Sorry if something is wrong, I don't have a C# editor installed here, but it's something like this:

 Array.Sort(
     itemTps, 
     delegate(ItemTp a, ItemTp b)
     {
          return secondList.IndexOf(a.Code) - secondList.IndexOf(b.Code);
     });

Note: it may not be the most efficient way, and also there is no checking whether the second list contains the Code at all.

[Edit] As Mehrdad said, Array.Sort doesn't work for generic IList<T>. To sort the array in place, you would need to use the ArrayList.Adapter method to create a wrapper, and then sort it. Since ArrayList.Sort doesn't support a delegate comparison, you need to put the anonymous delegate inside an implementation of IComparer<T>, .

If you need to sort it in a separate list, then it could have sense to use the logic above by creating an array first.

Upvotes: 0

anthony
anthony

Reputation: 41118

You'll need to create an IComparer that will compare items based on the state of your other list. The advantage of using an IComparer is that you'll be able to build caching logic into your class to avoid repeated IndexOf() lookups if you need that optimization. Also, you'll be able to maintain multiple "other" lists that can be used when appropriate.

class ItemTpComparer : IComparer<itemTp>
{
    private IList<codeTp> otherList;

    public ItemTpComparer(IList<codeTp> otherList)
    {
        this.otherList = otherList;
    }

    public int Compare(itemTp a, itemTp b)
    {
        return otherList.IndexOf(a.Code) - otherList.IndexOf(b.Code);
    }
}

And to perform the sort:

myList.Sort(new ItemTpComparer(otherList));

Upvotes: 9

Related Questions