Given the test case below how can I:
- Sort the IList<TestObject>based on the index of a matchingIdin theIList<int>list.
- Unmatched values are moved to the end of the list and sorted by their original index. In this case, since 3 and 4 do not exist in the index list, we expect to see list[3] == 3andlist[4] == 4.
- Whilst I know this can be achieved with linq, I need to resort the original list rather than creating a new one (due to how the list is stored).
- The source list must be an IList(I can't useList<T>)
Here's the test:
    public class TestObject
    {
        public int Id { get; set; }
    }
    [Test]
    public void Can_reorder_using_index_list()
    {
        IList<TestObject> list = new List<TestObject>
        {
            new TestObject { Id = 1 },
            new TestObject { Id = 2 },
            new TestObject { Id = 3 },
            new TestObject { Id = 4 },
            new TestObject { Id = 5 }
        };
        IList<int> indexList = new[] { 10, 5, 1, 9, 2 };
        // TODO sort
        Assert.That(list[0].Id, Is.EqualTo(5));
        Assert.That(list[1].Id, Is.EqualTo(1));
        Assert.That(list[2].Id, Is.EqualTo(2));
        Assert.That(list[3].Id, Is.EqualTo(3));
        Assert.That(list[4].Id, Is.EqualTo(4));
    }
Update:
As requested, this is what I did try, but 1) it only works with List<T> and 2) I'm not sure it's the most efficient way:
       var clone = list.ToList();
        list.Sort((x, y) =>
        {
            var xIndex = indexList.IndexOf(x.Id);
            var yIndex = indexList.IndexOf(y.Id);
            if (xIndex == -1)
            {
                xIndex = list.Count + clone.IndexOf(x);
            }
            if (yIndex == -1)
            {
                yIndex = list.Count + clone.IndexOf(y);
            }
            return xIndex.CompareTo(yIndex);
        });
Update 2:
Thanks to @leppie, @jamiec, @mitch wheat - this is the working code:
    public class TestObjectComparer : Comparer<TestObject>
    {
        private readonly IList<int> indexList;
        private readonly Func<TestObject, int> currentIndexFunc;
        private readonly int listCount;
        public TestObjectComparer(IList<int> indexList, Func<TestObject, int> currentIndexFunc, int listCount)
        {
            this.indexList = indexList;
            this.currentIndexFunc = currentIndexFunc;
            this.listCount = listCount;
        }
        public override int Compare(TestObject x, TestObject y)
        {
            var xIndex = indexList.IndexOf(x.Id);
            var yIndex = indexList.IndexOf(y.Id);
            if (xIndex == -1)
            {
                xIndex = listCount + currentIndexFunc(x);
            }
            if (yIndex == -1)
            {
                yIndex = listCount + currentIndexFunc(y);
            }
            return xIndex.CompareTo(yIndex);
        }
    }
    [Test]
    public void Can_reorder_using_index_list()
    {
        IList<TestObject> list = new List<TestObject>
        {
            new TestObject { Id = 1 },
            new TestObject { Id = 2 },
            new TestObject { Id = 3 },
            new TestObject { Id = 4 },
            new TestObject { Id = 5 }
        };
        IList<int> indexList = new[] { 10, 5, 1, 9, 2, 4 };
        ArrayList.Adapter((IList)list).Sort(new TestObjectComparer(indexList, x => list.IndexOf(x), list.Count));
        Assert.That(list[0].Id, Is.EqualTo(5));
        Assert.That(list[1].Id, Is.EqualTo(1));
        Assert.That(list[2].Id, Is.EqualTo(2));
        Assert.That(list[3].Id, Is.EqualTo(3));
        Assert.That(list[4].Id, Is.EqualTo(4));
    }
 
     
     
    