Generic List - moving an item within the list

前端 未结 10 677
后悔当初
后悔当初 2020-11-28 04:32

So I have a generic list, and an oldIndex and a newIndex value.

I want to move the item at oldIndex, to newIndex.

10条回答
  •  醉梦人生
    2020-11-28 05:00

    I created an extension method for moving items in a list.

    An index should not shift if we are moving an existing item since we are moving an item to an existing index position in the list.

    The edge case that @Oliver refers to below (moving an item to the end of the list) would actually cause the tests to fail, but this is by design. To insert a new item at the end of the list we would just call List.Add. list.Move(predicate, list.Count) should fail since this index position does not exist before the move.

    In any case, I've created two additional extension methods, MoveToEnd and MoveToBeginning, the source of which can be found here.

    /// 
    /// Extension methods for 
    /// 
    public static class ListExtensions
    {
        /// 
        /// Moves the item matching the  to the  in a list.
        /// 
        public static void Move(this List list, Predicate itemSelector, int newIndex)
        {
            Ensure.Argument.NotNull(list, "list");
            Ensure.Argument.NotNull(itemSelector, "itemSelector");
            Ensure.Argument.Is(newIndex >= 0, "New index must be greater than or equal to zero.");
    
            var currentIndex = list.FindIndex(itemSelector);
            Ensure.That(currentIndex >= 0, "No item was found that matches the specified selector.");
    
            // Copy the current item
            var item = list[currentIndex];
    
            // Remove the item
            list.RemoveAt(currentIndex);
    
            // Finally add the item at the new index
            list.Insert(newIndex, item);
        }
    }
    
    [Subject(typeof(ListExtensions), "Move")]
    public class List_Move
    {
        static List list;
    
        public class When_no_matching_item_is_found
        {
            static Exception exception;
    
            Establish ctx = () => {
                list = new List();
            };
    
            Because of = ()
                => exception = Catch.Exception(() => list.Move(x => x == 10, 10));
    
            It Should_throw_an_exception = ()
                => exception.ShouldBeOfType();
        }
    
        public class When_new_index_is_higher
        {
            Establish ctx = () => {
                list = new List { 1, 2, 3, 4, 5 };
            };
    
            Because of = ()
                => list.Move(x => x == 3, 4); // move 3 to end of list (index 4)
    
            It Should_be_moved_to_the_specified_index = () =>
                {
                    list[0].ShouldEqual(1);
                    list[1].ShouldEqual(2);
                    list[2].ShouldEqual(4);
                    list[3].ShouldEqual(5);
                    list[4].ShouldEqual(3);
                };
        }
    
        public class When_new_index_is_lower
        {
            Establish ctx = () => {
                list = new List { 1, 2, 3, 4, 5 };
            };
    
            Because of = ()
                => list.Move(x => x == 4, 0); // move 4 to beginning of list (index 0)
    
            It Should_be_moved_to_the_specified_index = () =>
            {
                list[0].ShouldEqual(4);
                list[1].ShouldEqual(1);
                list[2].ShouldEqual(2);
                list[3].ShouldEqual(3);
                list[4].ShouldEqual(5);
            };
        }
    }
    

提交回复
热议问题