在c#.net中的现有数组中添加新项目
如何在c#.net中的现有string数组中添加新项目。 我需要保留现有的数据。
如果你需要一个dynamic大小的数组,我会使用一个列表:
List<string> ls = new List<string>(); ls.Add("Hello");
这可能是一个解决办法;
Array.Resize(ref array, newsize); array[newsize - 1] = "newvalue"
但是对于dynamic大小的数组,我更愿意列表。
使用LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
我喜欢使用它,因为它是一行代码,非常方便embeddedswitch语句,简单的if语句或作为parameter passing。
编辑:
有些人不喜欢new[] { newitem }
因为它创build了一个小的单项临时数组。 这是一个使用Enumerable.Repeat
的版本,不需要创build任何对象(至less不是在表面上–.NET迭代器可能会在表下创build一堆状态机对象)。
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
如果您确定数组始终为null
,则可以将其简化为:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
注意,如果你想添加项目到一个有序的集合, List
可能是你想要的数据结构,而不是一个开始的数组。
C#中的数组是不可变的 ,例如string [],int []。 这意味着你不能调整它们。 您需要创build一个全新的arrays。
这里是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; } }
正如你所看到的,它创build一个新的大小的数组,复制源数组的内容,并将引用设置为新的数组。 这个提示是第一个参数的ref关键字。
有一些列表可以为新项目dynamic分配新插槽 。 这是例如List <T> 。 这些包含不可变数组,并在需要时调整它们的大小(List <T>不是链表实现!)。 ArrayList是没有generics(与对象数组)相同的东西。
LinkedList <T>是一个真正的链表实现。 不幸的是,你可以只添加LinkListNode <T> emenets到列表中,所以你必须把你自己的列表元素包装到这个节点types中。 我认为它的使用是不常见的。
Array.Resize(ref youur_array_name, your_array_name.Length + 1); your_array_name[your_array_name.Length - 1] = "new item";
很老的问题,但还是想补充一点。
如果你正在寻找一个单线,你可以使用下面的代码。 它结合了接受一个枚举的列表构造函数和“新”(因为问题引发)初始化语法。
myArray = new List<string>(myArray) { "add this" }.ToArray();
您可以使用基于LINQ的逻辑来扩展@Stephen Chung提供的答案,以使用genericstypes创build扩展方法。
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(); } }
然后你可以像这样直接在数组上调用它。
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... }
不可否认,AddRangeToArray()方法看起来有点矫枉过正,因为你有与Concat()相同的function,但是这样的结束代码可以直接与数组“工作”,而不是:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
如果由于某种原因你正在处理数组而不是列表,那么这个genericstypes的返回generics方法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; }
保持Array不可变且固定大小更好。
你可以模拟Add
by Extension Method
和IEnumerable.Concat()
public static class ArrayExtensions { public static string[] Add(this string[] array, string item) { return array.Concat(new[] {item}).ToArray(); } }
使用列表将是内存pipe理的最佳select。
我同意埃德。 C#并不像VB那样使用ReDim Preserve。 没有收集,你必须将数组复制到一个更大的。
使用扩展方法怎么样? 例如:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item) { return source.Union(new TSource[] { item }); }
例如:
string[] sourceArray = new [] { "foo", "bar" } string additionalItem = "foobar"; string result = sourceArray.Union(additionalItem);
注意,这模仿Linq的Uniion扩展(用于将两个数组合并成一个新的)的行为,并要求Linq库发挥作用。
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; }
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();
为什么不尝试使用Stringbuilder类。 它有诸如.insert和.append之类的方法。 你可以在这里阅读更多关于它的信息: http : //msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
不幸的是,使用列表在任何情况下都不起作用。 列表和数组实际上是不同的,并不是100%可互换的。 这将取决于情况,如果这是一个可以接受的工作。
由于这个问题不满意提供的答案,我想添加这个答案:)
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; } } } }
//所以如果你有一个现有的数组
/ /我的快速解决将是
var tempList = originalArray.ToList();
tempList.Add(的newitem);
//现在只需用新的数组replace原来的数组
originalArray = tempList.ToArray();