2

I have a list of items and a "selected" list (a subset of the full list). I want to implement a function that moves the sub list items to the bottom of the full list.

For instance, if I have selected the elements 2,4, & 6 from the list 0,1,2,3,4,5,6,7,8,9 I want this function to have the end result 0,1,3,5,7,8,9,2,4,6

Currently, I'm trying to use something like this, but I'm not sure how to define moveTo:

public object MoveLoopToBottom()
{
    if (selectedLoops.Count < 1)
        return null;

    foreach (ProfilerLoop selected in selectedLoops)
    {
        int moveFrom = ClonedLoops.IndexOf(selected);
        int moveTo = ;

        ClonedLoops.Move(moveFrom, moveTo);
    }

    return null;
}

I consulted this for how List.Move works: Generic List - moving an item within the list but it appears that it can't "move to end of list". List.Move can (at most) move to the "second-to-last" position (trying to move to the end of the list throws "OutOfRange Exception").

Instead of List.Move, I tried doing List.Remove then List.Add (or List.Add then List.RemoveAt) but calling List.Remove gives me problems with my foreach loop iterations (where List.Move does not).

Any suggestions?

Community
  • 1
  • 1
derekantrican
  • 1,891
  • 3
  • 27
  • 57
  • 1
    Create a new list of the selected items, remove those from the original list, then add them onto the end, something like `var newList = originalList.Except(selectedItems).AddRange(selectedItems);` – stuartd Jun 08 '16 at 16:52
  • 1
    @stuartd add `ToList()` after `Except` (as the `AddRange` method exists on a `List` and not on `IEnumerable`). – Styxxy Jun 08 '16 at 16:54
  • What about `list = list.OrderBy(i => selectedList.IndexOf(i)).ToList();`? That would put anything that isn't in `selectedList` first because `IndexOf` would be -1 then everything else in the order that it appears in `selectedList`. – juharr Jun 08 '16 at 16:56
  • Is `ClonedLoops` a generic list? That is, `List`? – Jim Mischel Jun 08 '16 at 17:09

2 Answers2

6

If I'm understanding this correctly, then you can simply remove and readd them without using a loop.

List<int> list = new List<int>(new int[] { 0,1,2,3,4,5,6,7,8,9 });
var selected  = new List<int>(new int[] { 0,1,2 });

list = list.Except(selected).ToList();
list.AddRange(selected);

This will remove all the selected Items from the list, then re-add them to the bottom.

DotNetFiddle

prospector
  • 3,389
  • 1
  • 23
  • 40
1

Actually, this worked for me (I'm not sure why it wasn't working before). @prospector 's answer is probably also quite valid (just didn't work for my unique situation)

public object MoveLoopToBottom()
{
    if (selectedLoops.Count < 1)
        return null;

    foreach (ProfilerLoop selected in selectedLoops)
    {
        int moveFrom = PartLoops.IndexOf(selected);

        ClonedLoops.Move(moveFrom, PartLoops.Count - 1);
    }

    return null;
}
derekantrican
  • 1,891
  • 3
  • 27
  • 57