我发现这比我想象的要困难得多.如何在列表中移动一部分项目?
例如,如果我有以下列表:
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)
请注意,从开头删除部分时,插入位置已更改.这使得它变得更加困难.
对于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方法Skip和Take,这些方法通常很有用。另外,您可能对该Enumerable.Range方法感兴趣,该方法可以像for循环一样轻松地创建范围。
然后可以像这样调用方法:
myList.MoveSection(8, 1, 3);
Run Code Online (Sandbox Code Playgroud)