How to add new item in existing string array in c#.net. i need to preserve the existing data.
如何在c#.net中添加现有字符串数组中的新项。我需要保存现有的数据。
19 个解决方案
#1
109
I would use a List if you need a dynamically sized array:
如果你需要一个动态大小的数组,我会使用列表:
List<string> ls = new List<string>();
ls.Add("Hello");
#2
78
That could be a solution;
这可能是一个解决方案;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
But for dynamic sized array I would prefer list too.
但是对于动态大小的数组,我也更喜欢列表。
#3
48
Using LINQ:
使用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.
我喜欢使用它,因为它是一行的,嵌入到switch语句、一个简单的if语句或作为参数传递非常方便。
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).
有些人不喜欢new[] {newitem},因为它创建了一个小的、一个项目、临时数组。这是一个使用Enumerable的版本。重复这一点不需要创建任何对象(至少在表面上不需要——. net迭代器可能在表下创建一堆状态机对象)。
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.
注意,如果要向有序集合添加项,List可能是您想要的数据结构,而不是要以数组开头。
#4
22
Arrays in C# are immutable, e.g. string[]
, int[]
. That means you can't resize them. You need to create a brand new array.
c#中的数组是不可变的,例如string[], int[]。这意味着你不能调整它们的大小。您需要创建一个全新的数组。
Here is the code for Array.Resize:
这是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.
正如您所看到的,它创建了一个新的数组,它具有新的大小,复制源数组的内容,并设置对新数组的引用。这里的提示是第一个参数的ref关键字。
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).
有一些列表可以动态地为新项目分配新位置。这是如列表< T >。它们包含不可变数组,并在需要时调整它们的大小(List
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.
LinkedList
#5
18
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.
如果您正在寻找一行程序,您可以使用下面的代码。它结合了接受可枚举的列表构造函数和“new”(既然提出了问题)初始化语法。
myArray = new List<string>(myArray) { "add this" }.ToArray();
#6
18
Array.Resize(ref youur_array_name, your_array_name.Length + 1);
your_array_name[your_array_name.Length - 1] = "new item";
#7
7
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.
通过使用基于LINQ的逻辑创建一个使用泛型类型的扩展方法,您可以扩展@Stephen Chung提供的答案。
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:
不可否认,AddRangeToArray()方法似乎有点过了头,因为您与Concat()具有相同的功能,但是与此相反,最终代码可以直接与数组“工作”:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
#8
5
if you are working a lot with arrays and not lists for some reason, this generic typed return generic method Add
might help
如果您经常使用数组而不是列表,那么这个泛型返回泛型方法Add可能会有所帮助
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;
}
#9
3
It's better to keeps Array immutable and fixed size.
you can simulate Add
by Extension Method
and IEnumerable.Concat()
可以通过扩展方法和IEnumerable.Concat()来模拟Add
public static class ArrayExtensions
{
public static string[] Add(this string[] array, string item)
{
return array.Concat(new[] {item}).ToArray();
}
}
#10
2
Using a list would be your best option for memory management.
使用列表是内存管理的最佳选择。
#11
1
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.
我同意Ed. c#并不能像VB那样简单地保存选区。如果没有集合,您将不得不将数组复制到较大的数组中。
#12
1
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.
注意,这模仿了Linq的单离子扩展(用于将两个数组组合成一个新的数组)的行为,并要求Linq库发挥作用。
#13
0
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;
}
#14
0
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();
#15
0
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
为什么不试试使用Stringbuilder类呢?它有.insert和.append等方法。你可以在这里阅读更多:http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
#16
0
Unfortunately using a list won't work in all situations. A list and an array are actually different and are not 100% interchangeable. It would depend on the circumstances if this would be an acceptable work around.
不幸的是,使用列表在所有情况下都不起作用。列表和数组实际上是不同的,并不是100%可互换的。如果这是一项可以接受的工作,这将取决于具体情况。
#17
0
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;
}
}
}
}
#18
0
//So if you have a existing array
/所以如果你有一个现有的数组
//my quick fix will be
//我很快就会修好。
var tempList = originalArray.ToList();
var tempList = originalArray.ToList();
tempList.Add(newitem);
tempList.Add(newitem);
//now just replace the original array with the new one
//现在用新的数组替换原来的数组
originalArray = tempList.ToArray();
originalArray = tempList.ToArray();
#19
0
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.
所有被提议的答案所做的都与他们想要避免的一样,创建一个新的数组并在其中添加一个新的条目,只会损失更多的开销。LINQ不是魔术,T的列表是一个带有缓冲区空间的数组,带有一些额外的空间,以避免在添加项时调整内部数组的大小。
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.
如果您需要灵活性,an可以创建一个足够大的列表用于传递,那么就这样做。否则,使用数组并共享线程安全的对象。另外,新的Span可以帮助共享数据,而不必复制列表。
To answer the question:
回答这个问题:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
#1
109
I would use a List if you need a dynamically sized array:
如果你需要一个动态大小的数组,我会使用列表:
List<string> ls = new List<string>();
ls.Add("Hello");
#2
78
That could be a solution;
这可能是一个解决方案;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
But for dynamic sized array I would prefer list too.
但是对于动态大小的数组,我也更喜欢列表。
#3
48
Using LINQ:
使用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.
我喜欢使用它,因为它是一行的,嵌入到switch语句、一个简单的if语句或作为参数传递非常方便。
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).
有些人不喜欢new[] {newitem},因为它创建了一个小的、一个项目、临时数组。这是一个使用Enumerable的版本。重复这一点不需要创建任何对象(至少在表面上不需要——. net迭代器可能在表下创建一堆状态机对象)。
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.
注意,如果要向有序集合添加项,List可能是您想要的数据结构,而不是要以数组开头。
#4
22
Arrays in C# are immutable, e.g. string[]
, int[]
. That means you can't resize them. You need to create a brand new array.
c#中的数组是不可变的,例如string[], int[]。这意味着你不能调整它们的大小。您需要创建一个全新的数组。
Here is the code for Array.Resize:
这是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.
正如您所看到的,它创建了一个新的数组,它具有新的大小,复制源数组的内容,并设置对新数组的引用。这里的提示是第一个参数的ref关键字。
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).
有一些列表可以动态地为新项目分配新位置。这是如列表< T >。它们包含不可变数组,并在需要时调整它们的大小(List
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.
LinkedList
#5
18
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.
如果您正在寻找一行程序,您可以使用下面的代码。它结合了接受可枚举的列表构造函数和“new”(既然提出了问题)初始化语法。
myArray = new List<string>(myArray) { "add this" }.ToArray();
#6
18
Array.Resize(ref youur_array_name, your_array_name.Length + 1);
your_array_name[your_array_name.Length - 1] = "new item";
#7
7
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.
通过使用基于LINQ的逻辑创建一个使用泛型类型的扩展方法,您可以扩展@Stephen Chung提供的答案。
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:
不可否认,AddRangeToArray()方法似乎有点过了头,因为您与Concat()具有相同的功能,但是与此相反,最终代码可以直接与数组“工作”:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
#8
5
if you are working a lot with arrays and not lists for some reason, this generic typed return generic method Add
might help
如果您经常使用数组而不是列表,那么这个泛型返回泛型方法Add可能会有所帮助
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;
}
#9
3
It's better to keeps Array immutable and fixed size.
you can simulate Add
by Extension Method
and IEnumerable.Concat()
可以通过扩展方法和IEnumerable.Concat()来模拟Add
public static class ArrayExtensions
{
public static string[] Add(this string[] array, string item)
{
return array.Concat(new[] {item}).ToArray();
}
}
#10
2
Using a list would be your best option for memory management.
使用列表是内存管理的最佳选择。
#11
1
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.
我同意Ed. c#并不能像VB那样简单地保存选区。如果没有集合,您将不得不将数组复制到较大的数组中。
#12
1
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.
注意,这模仿了Linq的单离子扩展(用于将两个数组组合成一个新的数组)的行为,并要求Linq库发挥作用。
#13
0
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;
}
#14
0
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();
#15
0
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
为什么不试试使用Stringbuilder类呢?它有.insert和.append等方法。你可以在这里阅读更多:http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
#16
0
Unfortunately using a list won't work in all situations. A list and an array are actually different and are not 100% interchangeable. It would depend on the circumstances if this would be an acceptable work around.
不幸的是,使用列表在所有情况下都不起作用。列表和数组实际上是不同的,并不是100%可互换的。如果这是一项可以接受的工作,这将取决于具体情况。
#17
0
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;
}
}
}
}
#18
0
//So if you have a existing array
/所以如果你有一个现有的数组
//my quick fix will be
//我很快就会修好。
var tempList = originalArray.ToList();
var tempList = originalArray.ToList();
tempList.Add(newitem);
tempList.Add(newitem);
//now just replace the original array with the new one
//现在用新的数组替换原来的数组
originalArray = tempList.ToArray();
originalArray = tempList.ToArray();
#19
0
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.
所有被提议的答案所做的都与他们想要避免的一样,创建一个新的数组并在其中添加一个新的条目,只会损失更多的开销。LINQ不是魔术,T的列表是一个带有缓冲区空间的数组,带有一些额外的空间,以避免在添加项时调整内部数组的大小。
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.
如果您需要灵活性,an可以创建一个足够大的列表用于传递,那么就这样做。否则,使用数组并共享线程安全的对象。另外,新的Span可以帮助共享数据,而不必复制列表。
To answer the question:
回答这个问题:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;