LINQ List <> Move Items Up and Down

Can you tell me the best way to move items in a List<> up and down.

For example, I have a class called Building and Building that has a list of objects List<Room> . Rooms are added to the building by name, but I use this structure to create a tree view. The user has the ability to move the room up and down inside the building.

I tried to use .Reverse(index, count) , but it did nothing:

 // can this item actually be moved up (is it at the first position in it 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); } } 
+3
source share
6 answers

Create a list extension. Call 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 } 

What to consider

  • Exception handling - what if you are trying to move the bottom element down or the top element up? You will get an index out of range because you cannot move them up or down.

  • You can improve this and prevent processing exceptions by expanding the functionality of moving the top item to the bottom item and the bottom item to the top item, etc.

+10
source

Just swap:

 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; } 
+4
source

Personally, I would make an extension method:

 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; } 

Using:

 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); } } 
+1
source

How to use SortedDictionary<int, Room> instead of a list. You can save the index as a dictionary key and simply change values โ€‹โ€‹when necessary.

0
source

Moving places with a room that used to be higher should do this:

 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; 

However, I'm not sure if this is the best object model for the situation; it is not clear that the order of the numbers in the list plays a role, and it is also unclear how you can "raise" a room - what does it mean?

It might be better to have a RoomPlacement class that combines the room and enough information to find it and work with it.

0
source

try the following:

 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); 
0
source

Source: https://habr.com/ru/post/1496511/


All Articles