jpi*_*son 123
我知道你说过"通用列表",但是你没有指定你需要使用List(T)类,所以这里是一个不同的镜头.
的的ObservableCollection(T)类有一个Move方法,你想要做什么.
public void Move(int oldIndex, int newIndex)
Run Code Online (Sandbox Code Playgroud)
它下面基本上是这样实现的.
T item = base[oldIndex];
base.RemoveItem(oldIndex);
base.InsertItem(newIndex, item);
Run Code Online (Sandbox Code Playgroud)
因此,您可以看到其他人建议的交换方法基本上就是ObservableCollection在其自己的Move方法中所做的工作.
UPDATE二○一五年十二月三十○日:你可以看到在源代码中移动和移动选项中corefx方法现在为自己没有使用反射/自.NET ILSpy是开源的.
Gar*_*ler 117
var item = list[oldIndex];
list.RemoveAt(oldIndex);
if (newIndex > oldIndex) newIndex--;
// the actual index could have shifted due to the removal
list.Insert(newIndex, item);
Run Code Online (Sandbox Code Playgroud)
小智 9
我知道这个问题已经过时但是我将这个 javascript代码的响应改编为C#.希望能帮助到你
public static void Move<T>(this List<T> list, int oldIndex, int newIndex)
{
// exit if possitions 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;
}
Run Code Online (Sandbox Code Playgroud)
List <T> .Remove()和List <T> .RemoveAt()不返回要删除的项目.
因此你必须使用这个:
var item = list[oldIndex];
list.RemoveAt(oldIndex);
list.Insert(newIndex, item);
Run Code Online (Sandbox Code Playgroud)
我创建了一个用于移动列表中项目的扩展方法。
如果我们要移动现有项目,则索引不应移动,因为我们要将项目移动到列表中的现有索引位置。
@Oliver 下面提到的边缘情况(将项目移到列表末尾)实际上会导致测试失败,但这是设计使然。要在列表末尾插入新List<T>.Add
项目,我们只需调用. list.Move(predicate, list.Count)
应该会失败,因为该索引位置在移动之前不存在。
无论如何,我创建了两个额外的扩展方法MoveToEnd
和MoveToBeginning
,其来源可以在此处找到。
/// <summary>
/// Extension methods for <see cref="System.Collections.Generic.List{T}"/>
/// </summary>
public static class ListExtensions
{
/// <summary>
/// Moves the item matching the <paramref name="itemSelector"/> to the <paramref name="newIndex"/> in a list.
/// </summary>
public static void Move<T>(this List<T> list, Predicate<T> 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<ArgumentException>(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<int> list;
public class When_no_matching_item_is_found
{
static Exception exception;
Establish ctx = () => {
list = new List<int>();
};
Because of = ()
=> exception = Catch.Exception(() => list.Move(x => x == 10, 10));
It Should_throw_an_exception = ()
=> exception.ShouldBeOfType<ArgumentException>();
}
public class When_new_index_is_higher
{
Establish ctx = () => {
list = new List<int> { 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<int> { 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);
};
}
}
Run Code Online (Sandbox Code Playgroud)
插入该项目目前oldIndex
是在newIndex
然后删除原始实例。
list.Insert(newIndex, list[oldIndex]);
if (newIndex <= oldIndex) ++oldIndex;
list.RemoveAt(oldIndex);
Run Code Online (Sandbox Code Playgroud)
您必须考虑到要删除的项目的索引可能会由于插入而发生变化。
归档时间: |
|
查看次数: |
170424 次 |
最近记录: |