Question

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;
  }
}
Was it helpful?

Solution

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

OTHER TIPS

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

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top