-2

I have the following list:

List<string> l=new List<string()>{"a","b","c","d","1","2","3","4","a1","b2","c3","d4"};

And I have oldIndex,size and newIndex.

Let's say for the above list oldIndex = 4,size = 4,newIndex = 0.

The output list I would like is:

{"1","2","3","4","a","b","c","d","a1","b2","c3","d4"};

The solution I've found is(which is not working for all cases):

for(int i=0;i<size;i++)
{
    if(oldIndex<newIndex)
    {
        var x=l[oldIndex];
        l.RemoveAt(oldIndex);
        l.Insert(newIndex+size-1,x);
    }
    else
    {
        var x=l[oldIndex+i];
        l.RemoveAt(oldIndex+i);
        l.Insert(newIndex+i,x);
    }
}

Is there any better way to this, perhaps using LINQ or something better, or is the above the only way to this?

I found the above answer from this link. The difference in this question is that I would like to move a block, and not just single element.

yajiv
  • 2,901
  • 2
  • 15
  • 25

2 Answers2

5

You can use the following for this:

List<string> removedRange = l.GetRange(oldIndex, size);
l.RemoveRange(oldIndex, size);
l.InsertRange(newIndex, removedRange);
Raviraj Palvankar
  • 879
  • 1
  • 5
  • 9
1

There are many different ways to do this.

Raviraj Palvankar's answer is probably the simplest, but to complement it (and since you specifically mentioned linq), here are a couple of (admittedly somewhat over-engineered) alternatives.

List<string> l = new List<string>{"a","b","c","d","1","2","3","4","a1","b2","c3","d4"};

var oldIndex = 4;
var size= 4;
var newIndex = 0;

To move:

var toMove = l.Skip(oldIndex).Take(size).ToList();
var newList = l.Take(oldIndex).ToList().Concat(l.Skip(oldIndex + size)).ToList();

newList.InsertRange(newIndex, toMove);

If you're able to move the section {"a","b","c","d"} instead (requires knowing a different new index, and does not require oldIndex, since it will be 0), then the move-operation itself becomes easier:

var newIndex = 4; // Replace previous value which was 0
var size= 4; // Elements a - d

var newList = l.Skip(size).ToList();
newList.InsertRange(newIndex, l.Take(size));

...and yet another way (which may actually be the simplest to read):

var oldIndex = 4;
var size= 4;

var toMove = l.Skip(oldIndex).Take(size).ToList();
var firstPart = l.Take(oldIndex);
var lastPart = l.Skip(oldIndex + size);
var combined = toMove.Concat(firstPart).Concat(lastPart);
Kjartan
  • 18,591
  • 15
  • 71
  • 96