To address the comment:
without loop is it possible with list because my performance has gone down because of loop
While it's not possible to avoid looping entirely and staying with the same structure (but see below), we can massively improve on the multiple inserts.
Every time you do an insert, all elements later in the list have to be copied within the internal structure. So for an n-element list there will be n-1 copy operations with a total of n * (n - 1) / 2 elements being copied (since the number of elements copied goes down each time. This means the time taken becomes roughly O(n2)—quadratic time. Which is bad.
We can do much better by first making the list double in size, and then copying the elements to their new positons. Since we only have to do n * 2 copies we are now doing this in O(n)—linear time.
To double the list's size we add it to itself. This is both convenient (we don't need to create another collection, or call Add() repeatedly) and takes advantage of the fact that List<T>.AddRange() has an optimisation for dealing well with lists being added to themselves:
list.AddRange(list);
Now, say the list contained {"1", "2", "3"}. It now contains {"1", "2", "3", "1", "2", "3"} and we want {"1", "1", "2", "2", "3", "3"}.
So we start with the last element of the original set (list[2]) and copy it to the last two positions, then move backwards through the list. Because we're moving backwards while copying forwards we don't end up copying into a position that has yet to be copied from (if we started in the beginning we'd just be copying the same "1" everywhere.
public static void DoupleUp(List<string> list)
{
if(list == null || list.Count == 0)
return;
list.AddRange(list);
for(int idx = list.Count / 2 - 1; idx != -1; --idx)
{
T el = list[idx];
list[idx * 2] = el;
list[idx * 2 + 1] = el;
}
}
Now all that's left is to realise that there's nothing specifically string-related about this, and genericise the method so we can use it on all lists:
public static void DoupleUp<T>(List<T> list)
{
if(list == null || list.Count == 0)
return;
list.AddRange(list);
for(int idx = list.Count / 2 - 1; idx != -1; --idx)
{
T el = list[idx];
list[idx * 2] = el;
list[idx * 2 + 1] = el;
}
}
After fixing the bug in Ankush's answer, I did a test run where I started with Enumerable.Range(0, 10).Select(i => i.ToString()).ToList() (the numbers 0 to 9 as strings) and then called his Operation on it 15 times, then went back to the original list and called my DoubleUp 15 times (15 isn't much, but it doubles each time so the final call is turning a list of 163840 elements into one with 327680 elements).
On my machine doing this with Operation takes around 12.8 seconds, while doing it with DoubleUp takes around 0.01 seconds.
If however you were going to iterate through this list only once, then you'd be much better creating the list on the fly:
public static IEnumerable<T> DoubleElements<T>(this IEnumerable<T> source)
{
foreach(T item in source)
{
yield return item;
yield return item;
}
}
Then you could just use foreach(string str in DoubleElements(myarray)) without even having to change from using an array.
You could even generalise this:
public static IEnumerable<T> RepeatElements<T>(this IEnumerable<T> source, int count)
{
foreach(T item in source)
for(int i = 0; i < count; ++i)
yield return item;
}
And then use foreach(string str in RepeatElements(myarray, 2)).
Now, if you really need to avoid looping, you'll have to do something very different again, and it will take away some possible further use:
public class RepeatList<T> : IList<T>
{
private readonly IList<T> _backing;
private readonly int _repeats;
public RepeatList(IList<T> backing, int repeats)
{
if(backing == null)
throw new ArgumentNullException("backing");
if(repeats < 1)
throw new ArgumentOutOfRangeException("repeats");
_backing = backing;
_repeats = repeats;
}
public RepeatList(int repeats)
: this(new List<T>(), repeats)
{
}
public T this[int index]
{
get { return _backing[index / _repeats]; }
set { _backing[index / _repeats] = value; }
}
public int Count
{
get { return _backing.Count * _repeats; }
}
public bool IsReadOnly
{
get { return _backing.IsReadOnly; }
}
public int IndexOf(T item)
{
int idx = _backing.IndexOf(item);
return idx >= 0 ? idx * _repeats : -1;
}
public void Insert(int index, T item)
{
_backing.Insert(index / _repeats, item);
}
public void RemoveAt(int index)
{
_backing.RemoveAt(index / _repeats);
}
public void Add(T item)
{
_backing.Add(item);
}
public void Clear()
{
_backing.Clear();
}
public bool Contains(T item)
{
return _backing.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
if(array == null)
throw new ArgumentNullException("array");
if(arrayIndex < 0)
throw new ArgumentOutOfRangeException("arrayIndex");
if(array.Length - arrayIndex < _backing.Count * _repeats)
throw new ArgumentException("array is too small to copy all elements starting from index " + arrayIndex);
foreach(T item in this)
array[arrayIndex++] = item;
}
public bool Remove(T item)
{
return _backing.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
foreach(T item in _backing)
for(int i = 0; i != _repeats; ++i)
yield return item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
This will create such a list in constant time: var rep = new RepeatList<string>(myArray, 2) returns pretty much immediately.
It mutates as myArray does (change element 2 of myArray and you change elements 4 and 5 of rep) and if used with a non-readonly backing list this goes both ways, including calls to Add in fact adding 2 elements. You can minimise the strangeness by making it readonly and having all of the mutating members throw NotSupportedException but it can also be useful to have the write-through happen.