Reputation:
How to add new item in existing string array in C#.net?
I need to preserve the existing data.
Upvotes: 159
Views: 552300
Reputation: 26468
A new Append<TSource>
method has been added to IEnumerable<TSource>
since .NET Framework 4.7.1 and .NET Core 1.0.
Here is how to use it:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Note that if you want to add the element at the beginning of the array, you can use the new Prepend<TSource>
method instead.
Upvotes: 13
Reputation: 421
So if you have a existing array, my quick fix will be
var tempList = originalArray.ToList();
tempList.Add(newitem);
Now just replace the original array with the new one
originalArray = tempList.ToArray();
Upvotes: 8
Reputation: 4411
All proposed answers do the same as what they say they'd like to avoid, creating a new array and adding a new entry in it only with lost more overhead. LINQ is not magic, list of T is an array with a buffer space with some extra space as to avoid resizing the inner array when items are added.
All the abstractions have to solve the same issue, create an array with no empty slots that hold all values and return them.
If you need the flexibility an can create a large enough list that you can use to pass then do that. else use an array and share that thread-safe object. Also, the new Span helps to share data without having to copy the lists around.
To answer the question:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Upvotes: 5
Reputation: 4479
Arrays in C# are immutable, e.g. string[]
, int[]
. That means you can't resize them. You need to create a brand new array.
Here is the code for Array.Resize:
public static void Resize<T>(ref T[] array, int newSize)
{
if (newSize < 0)
{
throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
T[] sourceArray = array;
if (sourceArray == null)
{
array = new T[newSize];
}
else if (sourceArray.Length != newSize)
{
T[] destinationArray = new T[newSize];
Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
array = destinationArray;
}
}
As you can see it creates a new array with the new size, copies the content of the source array and sets the reference to the new array. The hint for this is the ref keyword for the first parameter.
There are lists that can dynamically allocate new slots for new items. This is e.g. List<T>. These contain immutable arrays and resize them when needed (List<T> is not a linked list implementation!). ArrayList is the same thing without Generics (with Object array).
LinkedList<T> is a real linked list implementation. Unfortunately you can add just LinkListNode<T> elements to the list, so you must wrap your own list elements into this node type. I think its use is uncommon.
Upvotes: 31
Reputation: 271
Array.Resize(ref youur_array_name, your_array_name.Length + 1);
your_array_name[your_array_name.Length - 1] = "new item";
Upvotes: 27
Reputation: 3395
What about using an extension method? For instance:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
for instance:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Note this mimics this behavior of Linq's Uniion extension (used to combine two arrays into a new one), and required the Linq library to function.
Upvotes: 2
Reputation: 3506
Very old question, but still wanted to add this.
If you're looking for a one-liner, you can use the code below. It combines the list constructor that accepts an enumerable and the "new" (since question raised) initializer syntax.
myArray = new List<string>(myArray) { "add this" }.ToArray();
Upvotes: 37
Reputation: 2210
if you are working a lot with arrays and not lists for some reason, this generic typed return generic method Add
might help
public static T[] Add<T>(T[] array, T item)
{
T[] returnarray = new T[array.Length + 1];
for (int i = 0; i < array.Length; i++)
{
returnarray[i] = array[i];
}
returnarray[array.Length] = item;
return returnarray;
}
Upvotes: 6
Reputation: 2679
Since this question not satisfied with provided answer, I would like to add this answer :)
public class CustomArrayList<T>
{
private T[] arr; private int count;
public int Count
{
get
{
return this.count;
}
}
private const int INITIAL_CAPACITY = 4;
public CustomArrayList(int capacity = INITIAL_CAPACITY)
{
this.arr = new T[capacity]; this.count = 0;
}
public void Add(T item)
{
GrowIfArrIsFull();
this.arr[this.count] = item; this.count++;
}
public void Insert(int index, T item)
{
if (index > this.count || index < 0)
{
throw new IndexOutOfRangeException( "Invalid index: " + index);
}
GrowIfArrIsFull();
Array.Copy(this.arr, index, this.arr, index + 1, this.count - index);
this.arr[index] = item; this.count++; }
private void GrowIfArrIsFull()
{
if (this.count + 1 > this.arr.Length)
{
T[] extendedArr = new T[this.arr.Length * 2];
Array.Copy(this.arr, extendedArr, this.count);
this.arr = extendedArr;
}
}
}
}
Upvotes: -1
Reputation: 6787
you can simulate Add
by Extension Method
and IEnumerable.Concat()
public static class ArrayExtensions
{
public static string[] Add(this string[] array, string item)
{
return array.Concat(new[] {item}).ToArray();
}
}
Upvotes: 7
Reputation: 14605
Using LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
I like using this as it is a one-liner and very convenient to embed in a switch statement, a simple if-statement, or pass as argument.
EDIT:
Some people don't like new[] { newitem }
because it creates a small, one-item, temporary array. Here is a version using Enumerable.Repeat
that does not require creating any object (at least not on the surface -- .NET iterators probably create a bunch of state machine objects under the table).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
And if you are sure that the array is never null
to start with, you can simplify it to:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Notice that if you want to add items to a an ordered collection, List
is probably the data structure you want, not an array to start with.
Upvotes: 55
Reputation: 1778
You can expand on the answer provided by @Stephen Chung by using his LINQ based logic to create an extension method using a generic type.
public static class CollectionHelper
{
public static IEnumerable<T> Add<T>(this IEnumerable<T> sequence, T item)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(new[] { item });
}
public static T[] AddRangeToArray<T>(this T[] sequence, T[] items)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(items).ToArray();
}
public static T[] AddToArray<T>(this T[] sequence, T item)
{
return Add(sequence, item).ToArray();
}
}
You can then call it directly on the array like this.
public void AddToArray(string[] options)
{
// Add one item
options = options.AddToArray("New Item");
// Add a
options = options.AddRangeToArray(new string[] { "one", "two", "three" });
// Do stuff...
}
Admittedly, the AddRangeToArray() method seems a bit overkill since you have the same functionality with Concat() but this way the end code can "work" with the array directly as opposed to this:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
Upvotes: 8
Reputation: 14685
Why not try out using the Stringbuilder class. It has methods such as .insert and .append. You can read more about it here: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Upvotes: 0
Reputation: 1329
string str = "string ";
List<string> li_str = new List<string>();
for (int k = 0; k < 100; i++ )
li_str.Add(str+k.ToString());
string[] arr_str = li_str.ToArray();
Upvotes: 2
Reputation: 1
private static string[] GetMergedArray(string[] originalArray, string[] newArray)
{
int startIndexForNewArray = originalArray.Length;
Array.Resize<string>(ref originalArray, originalArray.Length + newArray.Length);
newArray.CopyTo(originalArray, startIndexForNewArray);
return originalArray;
}
Upvotes: 0
Reputation: 16086
That could be a solution;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
But for dynamic sized array I would prefer list too.
Upvotes: 116
Reputation: 43158
I agree with Ed. C# does not make this easy the way VB does with ReDim Preserve. Without a collection, you'll have to copy the array into a larger one.
Upvotes: 1
Reputation: 124632
I would use a List if you need a dynamically sized array:
List<string> ls = new List<string>();
ls.Add("Hello");
Upvotes: 128