C#移动列表中的一部分项目

rot*_*rcz 8 c# list

我发现这比我想象的要困难得多.如何在列表中移动一部分项目?

例如,如果我有以下列表:

List<int> myList = new List<int>();
for(int i=0; i<10; i++) {
    myList.Add(i);
}
Run Code Online (Sandbox Code Playgroud)

此列表将包含{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }.

如何移动List的各个部分?说我想转移{ 7, 8, 9 }到第四个索引,使其成为:

{ 0, 1, 2, 3, 7, 8, 9, 4, 5, 6 }
Run Code Online (Sandbox Code Playgroud)

或者说,我想移动{ 1, 2 }{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }的第八指数,使其:

{ 0, 3, 4, 5, 6, 7, 1, 2, 8, 9 }
Run Code Online (Sandbox Code Playgroud)

谁能提供一些代码?像下面这样需要3个值的东西会很棒.

MoveSection(insertionPoint, startIndex, endIndex)
Run Code Online (Sandbox Code Playgroud)

请注意,从开头删除部分时,插入位置已更改.这使得它变得更加困难.

Ben*_*ich 5

对于IEnumerable使用迭代器块的任何人,都可以相对简单地进行此操作。我总是发现使用该yield return构造可以以一种简洁明了的方式解决此类问题。在这里,为了方便使用,我还将该方法制成了扩展方法:

public static class Extension
{
   public static IEnumerable<T> MoveSection<T>(this IEnumerable<T> @this, int insertionPoint, int startIndex, int endIndex)
   {
      var counter = 0;
      var numElements = endIndex - startIndex;
      var range = Enumerable.Range(startIndex, numElements);
      foreach(var i in @this)
      {
          if (counter == insertionPoint) {
              foreach(var j in @this.Skip(startIndex).Take(numElements)) {
                  yield return j;
              }
          }
          if (!range.Contains(counter)) {
              yield return i;
          }
          counter++;
      }             
      //The insertion point might have been after the entire list:
      if (counter++ == insertionPoint) {
          foreach(var j in @this.Skip(startIndex).Take(numElements)) {
              yield return j;
          }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我使用Linq方法SkipTake,这些方法通常很有用。另外,您可能对该Enumerable.Range方法感兴趣,该方法可以像for循环一样轻松地创建范围。

然后可以像这样调用方法:

myList.MoveSection(8, 1, 3);
Run Code Online (Sandbox Code Playgroud)