LINQ列表<>上下移动元素

时间:2013-02-28 10:50:39

标签: c# asp.net-mvc asp.net-mvc-3 linq

是否有可能告诉我在List<>上下移动元素的最佳方式。

例如,我有一个名为Building and Building的类有一个Rooms对象列表List<Room>。房间按名称添加到建筑物中,但我使用此结构生成树视图。用户可以选择在建筑物内上下移动房间。

我试图使用.Reverse(index, count),但这似乎没有做任何事情:

// can this item actually be moved up (is it at the first position in it's current parent?)
if (moveDirection == MoveDirection.UP)
{
    int roomIndex = parentBuilding.Rooms.IndexOf(room);

    if (roomIndex == 0)
    {
        return;
    }
    else
    {
        // move this room up.                            
        parentBuilding.Rooms.Reverse(roomIndex, 1);
    }
}

6 个答案:

答案 0 :(得分:10)

创建列表扩展名。请致电List<T>.Move(1, MoveDirection.Up)

public static class ListExtensions
{
    public static void Move<T>(this IList<T> list, int iIndexToMove, 
        MoveDirection direction)
    {

        if (direction == MoveDirection.Up)
        {
            var old = list[iIndexToMove - 1];
            list[iIndexToMove - 1] = list[iIndexToMove];
            list[iIndexToMove] = old;
        }
        else
        {
            var old = list[iIndexToMove + 1];
            list[iIndexToMove + 1] = list[iIndexToMove];
            list[iIndexToMove] = old;
        }
    }
}

public enum MoveDirection
{
    Up,
    Down
}

需要考虑的事项

  • 异常处理 - 如果您尝试移动底部,该怎么办? 元素向下或顶部元素?您将获得超出范围的索引 因为你不能向上或向下移动它们。

  • 您可以通过扩展来改进这一点并防止处理异常 将顶部元素移动到底部元素的功能 底部元素到顶部元素等。

答案 1 :(得分:4)

做一个交换:

int roomIndex = parentBuilding.Rooms.IndexOf(room);

if (roomIndex == 0)
{
    return;
}
else
{
    // move this room up.                            
    var temp = parentBuilding.Rooms[index-1];
    parentBuilding.Rooms[index-1] = parentBuilding.Rooms[index];
    parentBuilding.Rooms[index] = temp;
}

答案 2 :(得分:1)

就个人而言,我会制作扩展方法:

static void Swap<TSource>(this IList<TSource> source, int fromIndex, int toIndex)
{
    if (source == null)
        throw new ArgumentNullExcpetion("source");

    TSource tmp = source[toIndex];
    source[toIndex] = source[fromIndex];
    source[fromIndex] = tmp;
}

用法:

if (moveDirection == MoveDirection.UP)
{
    int roomIndex = parentBuilding.Rooms.IndexOf(room);

    if (roomIndex == 0)
    {
        return;
    }
    else
    {
        // move this room up.                            
        parentBuilding.Rooms.Swap(roomIndex, roomIndex - 1);
    }
}

答案 3 :(得分:0)

如何使用SortedDictionary<int, Room>而不是列表。您可以将索引存储为词典的键,只需在需要时交换值。

答案 4 :(得分:0)

与以前的房间交换位置应该这样做:

int roomIndex = parentBuilding.Rooms.IndexOf(room);

if (roomIndex == 0)
{
    return;
}

var wasAbove = parentBuilding.Rooms[roomIndex - 1];
parentBuilding.Rooms[roomIndex - 1] = room;
parentBuilding.Rooms[roomIndex] = wasAbove;

那就是说,我不确定这是最适合这种情况的对象模型;目前还不清楚列表中的房间顺序是否起作用,而且房间如何“向上移动”也不清楚 - 这意味着什么?

最好有一个聚合房间的RoomPlacement课程和足够的信息来定位,并改为使用它。

答案 5 :(得分:0)

试试这个:

int newIndex = whateverIndexYouWantItAt;

int oldIndex = parentBuilding.Rooms.IndexOf(room);
var item = parentBuilding.Rooms[oldIndex];

list.RemoveAt(oldIndex);

if (newIndex > oldIndex) newIndex--; 

parentBuilding.Rooms.Insert(newIndex, item);