0

I receive a sorted list of integers which I would like to use to sort a ListCollectionView via ListCollectionView.CustomSort. This property accepts an IComparer and I've created one but, as expected, I can only compare values on generic objects x and y.

public List<int> SortedIds = new List<int> { 13, 7, 5, 3, 1 };
public class Item {
  int Id { get; set; }    
}

public class IdComparer : IComparer<Item> {
  public int Compare(Item x, Item y) {
    // Comparisons 
    // ???
    // return 0;
  }
}
erodewald
  • 1,815
  • 20
  • 45
  • If you could sort any way you wanted, how would you sort it? – Scott Chamberlain Mar 25 '13 at 21:48
  • Why is `IdComparer` not an `IComparer`? How is `Item` related to the `SortedIds` list? There's a disconnect here. – Matt Ball Mar 25 '13 at 21:48
  • @MattBall The class Item is extremely simplified for this question. SortedIds actually exist on a separate object and the `Item` does not have access to that. There are many properties on `Item` of value. – erodewald Mar 25 '13 at 21:53
  • @ScottChamberlain That's a pretty vague question. I want to sort the `List` of `Item` by their `Id` in the order of `SortedIds`. Again, not sure if that's what you wanted to know. – erodewald Mar 25 '13 at 22:06
  • @Erode Yes, I did not understand that was your question, that was exactly what i was looking for. – Scott Chamberlain Mar 25 '13 at 22:20

3 Answers3

1

Maybe you want to return SortedIds.IndexOf(x.Id).CompareTo(SortedIds.IndexOf(y.Id))?

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
1

If you want to compare by their index in your SortedIds list, you can do:

public class IdComparer : IComparer<Item> {
    private readonly Dictionary<int, int> idIndexes;
    public IdComparer(IEnumerable<int> sortedIds)
    {
        idIndexes = sortedIds
            .Select((id, idx) => new { Id = id, Index = idx })
            .ToDictionary(p => p.Id, p.Index);
    }

    public int Compare(Item x, Item y) {
        xIndex = idIndexes[x.Id];
        yIndex = idIndexes[y.Id]
        return xIndex.CompareTo(yIndex);
    }
}

However you could use linq:

IEnumerable<Item> sorted = SortedIds
    .Select((id, idx) => new { Id = id, Index = idx })
    .Join(items, p => i.Id, item => item.Id, (p, item) => new { Item = item, Index = idx })
    .OrderBy(p => p.Index)
    .Select(p => p.Item);
Lee
  • 142,018
  • 20
  • 234
  • 287
0

You can use OrderBy to order by any field you want. Like this:

List<Item> sortedById = items.OrderBy(x=>x.Id).ToList();

and

List<Item> sortedByEgo = items.OrderBy(x=>x.Ego).ToList();

(for types that don't compare directly you can also use the variant of OrderBy that takes an IComparer argument, but that's not needed here if Id and Ego are ints).

redtuna
  • 4,586
  • 21
  • 35