0

is it possible to block set a list with a value after a particular index, fast?

How is the below logic can be written in C#?. I could use a different collection if I can do the same.

List<int> mylist = new List<int>(10);

int index = 3;
int value = 11;
mylist.SetValuesafterIndex(index, value);

EDIT:

Clarification: I mean, I want indices 3 to 9 inclusive to be set to value 11

Jimmy
  • 3,224
  • 5
  • 29
  • 47

4 Answers4

1

The method that you want is not provided by List<T>. So, whilst it is something of a statement of the obvious, you could perfectly well write:

for (int i = index; i < list.Count; i++) 
    list[i] = value;

The only other option that springs to mind is to use RemoveRange to remove all items from Index to the end, and then call AddRange to add your new values.

Since you state performance as being an issue, you should carry out some measurements of the options with your real-world usage scenarios.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I tend to agree. RemoveRange and AddRange looks like the only option. Will wait for some more time for any magical ideas :-). – Jimmy Jan 23 '14 at 00:03
  • I suspect that there will be scenarios where the `for` loop is faster, and other scenarios where the alternative is faster. – David Heffernan Jan 23 '14 at 00:07
  • I see what you mean. msdn says addrange and removerange are o(n) operations. I was under a different impression after reading this answer where Jon suggest to use addrange for list initialization http://stackoverflow.com/questions/466946/how-to-initialize-a-listt-to-a-given-size-as-opposed-to-capacity – Jimmy Jan 23 '14 at 00:14
0

Try the following

mylist[index] = value;

It's unclear if you want it to be at index or index + 1. Just adjust the above as appropriate

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
0

You can write a generic method like this:

 static void SetRangeValues<T>(List<T> list,int start,int end,T value)
 {
       if(end > list.Count() || start < 0) 
           throw new ArgumentOutOfRangeException();

        for(int i=start;i<end;i++)
        {
            list[i] = value;
        }
 }

And you can use it like this:

var list = new List<int>();
list.AddRange(Enumerable.Range(0,10));

Console.WriteLine("Before: ");
list.ForEach(Console.WriteLine);

SetRangeValues(ref list, 3, 10, 2000);

Console.WriteLine("After: ");
list.ForEach(Console.WriteLine);

// Output:

Before:
0
1
2
3
4
5
6
7
8
9
After:
0
1
2
2000
2000
2000
2000
2000
2000
2000

If you want to set values until the end of the List, simply you can pass list.Count as end parameter:

SetRangeValues(list, 3, list.Count(), 2000);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • It's a little pointless testing for and throwing `ArgumentOutOfRangeException` given that `List` already does so. You may as well let it do the work and so perform one fewer check. – David Heffernan Jan 23 '14 at 00:14
  • @DavidHeffernan you right,but maybe OP wants to change that behavior,maybe he want to display a message and return from the function immediately. – Selman Genç Jan 23 '14 at 00:28
0

Not so sure about performance, but an one line answer could be:

myList.AddRange(Enumerable.Repeat(0, index).Concat(Enumerable.Repeat(value, 10 - index)));
Lowkey
  • 836
  • 5
  • 12