C# Move Items In List Order Without Changing Relative Positions

I think there are two issues here. (1) you need to keep track of an empty position at the beginning of the list. (2) you need to complete the swap of each item before proceeding to the next (this allows the f5 to move to the end of the list).

Here’s how I would do it:

int[] indices = Enumerable.Range(-1, primaryList.Count + 1).ToArray();
foreach (var item in itemsToMove)
    var index = primaryList.IndexOf(item);
    (indices[index], indices[index + 1]) = (indices[index + 1], indices[index]);
primaryList = indices.Where(i => i != -1).Select(i => primaryList[i]).ToList();

indices is an array of integers with a -1 indicating the start of the list.

Then we loop through the itemsToMove, find each elements index in the original list and swap the index with the previous element. Remember that we added - to the start of the list so then we are swapping element index and index + 1 to swap the current and the previous indices.

Then it’s a simple matter to filtering out the -1 and pulling out the values from the original list at their new index locations.

The result I get is:

f1, f2, f4, f3, f6, f7, f5

Here’s some more explanation:

We’re starting with this array:


We want to be able to swap these elements with the element to the left:


There’s no element to the left of f1 so let’s make one. We now have this array:


Now we do the four swaps:


Then we rebuild the original list at the new indices and drop the -1:


Here’s how to reverse the operation:

var reversed =
        .Where(i => i != -1)
        .Select((i, n) => (i, n))
        .OrderBy(x => x.i)
        .Select(x => x.n)
        .Select(i => primaryList[i])

This is done after primaryList has been modified.

Here’s how to do the “move forward” operation:

int[] indices = Enumerable.Range(0, primaryList.Count + 1).ToArray();
foreach (var item in itemsToMove.AsEnumerable().Reverse())
    var index = primaryList.IndexOf(item);
    (indices[index], indices[index + 1]) = (indices[index + 1], indices[index]);
primaryList = indices.Where(i => i != primaryList.Count).Select(i => primaryList[i]).ToList();

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top