Generic List - moving an item within the list

前端 未结 10 580
后悔当初
后悔当初 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:13

    I know this question is old but I adapted THIS response of javascript code to C#. Hope it helps

    public static void Move<T>(this List<T> list, int oldIndex, int newIndex)
    {
        // exit if positions are equal or outside array
        if ((oldIndex == newIndex) || (0 > oldIndex) || (oldIndex >= list.Count) || (0 > newIndex) ||
            (newIndex >= list.Count)) return;
        // local variables
        var i = 0;
        T tmp = list[oldIndex];
        // move element down and shift other elements up
        if (oldIndex < newIndex)
        {
            for (i = oldIndex; i < newIndex; i++)
            {
                list[i] = list[i + 1];
            }
        }
            // move element up and shift other elements down
        else
        {
            for (i = oldIndex; i > newIndex; i--)
            {
                list[i] = list[i - 1];
            }
        }
        // put element from position 1 to destination
        list[newIndex] = tmp;
    }
    
    0 讨论(0)
  • 2020-11-28 05:19

    I know you said "generic list" but you didn't specify that you needed to use the List(T) class so here is a shot at something different.

    The ObservableCollection(T) class has a Move method that does exactly what you want.

    public void Move(int oldIndex, int newIndex)
    

    Underneath it is basically implemented like this.

    T item = base[oldIndex];
    base.RemoveItem(oldIndex);
    base.InsertItem(newIndex, item);
    

    So as you can see the swap method that others have suggested is essentially what the ObservableCollection does in it's own Move method.

    UPDATE 2015-12-30: You can see the source code for the Move and MoveItem methods in corefx now for yourself without using Reflector/ILSpy since .NET is open source.

    0 讨论(0)
  • 2020-11-28 05:21

    Insert the item currently at oldIndex to be at newIndex and then remove the original instance.

    list.Insert(newIndex, list[oldIndex]);
    if (newIndex <= oldIndex) ++oldIndex;
    list.RemoveAt(oldIndex);
    

    You have to take into account that the index of the item you want to remove may change due to the insertion.

    0 讨论(0)
  • 2020-11-28 05:21

    This is how I implemented a move element extension method. It handles moving before/after and to the extremes for elements pretty well.

    public static void MoveElement<T>(this IList<T> list, int fromIndex, int toIndex)
    {
      if (!fromIndex.InRange(0, list.Count - 1))
      {
        throw new ArgumentException("From index is invalid");
      }
      if (!toIndex.InRange(0, list.Count - 1))
      {
        throw new ArgumentException("To index is invalid");
      }
    
      if (fromIndex == toIndex) return;
    
      var element = list[fromIndex];
    
      if (fromIndex > toIndex)
      {
        list.RemoveAt(fromIndex);
        list.Insert(toIndex, element);
      }
      else
      {
        list.Insert(toIndex + 1, element);
        list.RemoveAt(fromIndex);
      }
    }
    
    0 讨论(0)
提交回复
热议问题