Bob
Bob

Reputation: 4386

.NET IComparable: how to implement

I have a collection of objects I need to order but not sure how.

There is a string property called, say Prop1, that I want to sort by. And I want to sort based on a List of strings which contain all possible values of Prop1.

List<string> precedence = new List<string>() { "firstPrecedence", "secondPrecedence" ....

How would I implement my CompareTo(object obj) method?

I'm trying with this but don't really know what i'm doing!

    public int CompareTo(object obj)
    {
        List<string> precedence = new List<string>() { "firstPrecedence", "secondPrecedence", "thirdPrecedence" };

        Filter filterOther = obj as Filter;

        foreach (var item in precedence)
        {
            return String.Compare(filterOther.FilterValue, item);
        }
        return 0;
    }

Upvotes: 1

Views: 428

Answers (4)

Otiel
Otiel

Reputation: 18743

Create a new class of your object that you want to sort:

public class MySortableObject: IComparable {

    private string str;

    public MySortableObject(string _str) {
        this.str = _str;
    }

    int IComparable.CompareTo(object obj) {
        MySortableObject comparedObj = (MySortableObject) obj;

        // Implement here the code that will compare the current object (this) and the compared object (comparedObj)
        // It must return -1 if this instance precedes comparedObj in the sort order
        // It must return 1 if this instance follows comparedObj in the sort order
        // It must return 0 if this instance occurs in the same position in the sort order as comparedObj

        // Use for example String.CompareTo() method to implement this, or your own code (with if(), switch()... whatever you need)
    }
}

Upvotes: 0

Ankur
Ankur

Reputation: 33657

Using LINQ:

precedence.SelectMany(p => objs.Where(o => o.Prop1 == p));

OR

objs.Select(s => new { Index = precedence.IndexOf(s.Prop1), Obj = s })
                .OrderBy(a => a.Index).Select(a => a.Obj);

Upvotes: 0

Adam Houldsworth
Adam Houldsworth

Reputation: 64517

Well, if your precedence list is known at compile time and you can use it, then you can compare the indexes of the values you are sorting:

private static List<string> Precedence = new List<string>() { "item1", "item2", "item3" }; // etc

public int CompareTo(object obj)
{
    Filter item = obj as Filter; // Assume not null.   
    int otherIndex = Precedence.IndexOf(item.FilterValue);
    int thisIndex = Precedence.IndexOf(this.FilterValue); // Assume 'this' is a Filter

    // This may need to be otherIndex.CompareTo(thisIndex) depending on the direction of sort you want.
    return thisIndex.CompareTo(otherIndex);
}

If the FilterValue value is not in the list, IndexOf will return -1, which will still work in the sorting implementation here, but may sort at the top or bottom of the list... I can never remember which!

Note that the CompareTo method returns either 0, something less than 0, or something greater than 0. Usually, -1, 0, and 1.

Also, there is a generic IComparable<> which will allow you to achieve this in a more strongly-typed way:

public class Filter : IComparable<Filter>
{

}

And I'm sure some clever person will give you a solution in LINQ...

Upvotes: 1

Dean Chalk
Dean Chalk

Reputation: 20471

try this (assuming you have a List<Filter> )

filterObjectList.Sort((f1,f2) => precedence.IndexOf(f1.FilterValue).CompareTo(precedence.IndexOf(f2.FilterValue));

Upvotes: 1

Related Questions