在c#.net中的现有数组中添加新项

时间:2008-10-30 07:02:12

标签: c# .net

如何在C#.net?

中的现有字符串数组中添加新项目

我需要保留现有数据。

20 个答案:

答案 0 :(得分:115)

如果您需要动态大小的数组,我会使用List:

List<string> ls = new List<string>();
ls.Add("Hello");

答案 1 :(得分:89)

这可能是一个解决方案;

Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"

但对于动态大小的数组,我也更喜欢列表。

答案 2 :(得分:49)

使用LINQ:

arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();

我喜欢使用它,因为它是一个单行且非常方便嵌入switch语句,简单的if语句或传递为参数。

修改

有些人不喜欢new[] { newitem }因为它会创建一个小的,单项的临时数组。这是一个使用Enumerable.Repeat的版本,它不需要创建任何对象(至少不在表面上 - .NET迭代器可能会在表下创建一堆状态机对象。)

arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();

如果您确定该数组永远不会null开始,您可以将其简化为:

arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();

请注意,如果要将项添加到有序集合中,List可能是您想要的数据结构,而不是要开始的数组。

答案 3 :(得分:25)

C#中的数组是不可变的,例如string[]int[]。这意味着你无法调整它们的大小。您需要创建一个全新的阵列。

以下是 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;
    }
}

如您所见,它创建了一个具有新大小的新数组,复制源数组的内容并设置对新数组的引用。对此的提示是第一个参数的 ref 关键字。

有些列表可以为新项目动态分配新广告位。这是例如列表&LT; T&GT; 。它们包含不可变数组,并在需要时调整它们的大小(List&lt; T&gt;不是链表实现!)。没有Generics( Object 数组), ArrayList 是一回事。

LinkedList&lt; T&gt; 是真正的链接列表实现。很遗憾,您只需添加LinkListNode&lt; T&gt;列表中的元素,因此您必须将自己的列表元素包装到此节点类型中。我认为它的使用并不常见。

答案 4 :(得分:22)

 Array.Resize(ref youur_array_name, your_array_name.Length + 1);
 your_array_name[your_array_name.Length - 1] = "new item";

答案 5 :(得分:21)

非常古老的问题,但仍想添加此内容。

如果您正在寻找单行,您可以使用以下代码。它结合了接受可枚举的列表构造函数和&#34; new&#34; (自提出问题)初始化语法。

myArray = new List<string>(myArray) { "add this" }.ToArray();

答案 6 :(得分:7)

您可以使用基于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();
    }

}

然后你可以直接在数组上调用它。

    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()相同的功能,但这样终端代码可以直接与数组“一起工作” 与此相反:

options = options.Concat(new string[] { "one", "two", "three" }).ToArray();

答案 7 :(得分:5)

自.NET Framework 4.7.1和.NET Core 1.0以来,已向IEnumerable<TSource>添加了新的Append<TSource>方法。

这里是使用方法:

var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four

请注意,如果要在数组的开头添加元素,则可以改用新的Prepend<TSource>方法。

答案 8 :(得分:5)

如果由于某种原因你正在使用数组而不是列表,那么这种通用类型的返回泛型方法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)

保持数组不可变和固定大小更好。

您可以AddExtension Method

模拟IEnumerable.Concat()
public static class ArrayExtensions
    {
        public static string[] Add(this string[] array, string item)
        {
            return array.Concat(new[] {item}).ToArray();
        }
    }

答案 10 :(得分:2)

使用列表将是内存管理的最佳选择。

答案 11 :(得分:2)

所有提议的答案与他们所说的他们想要避免的内容相同,创建一个新阵列并在其中添加新条目只会丢失更多开销。 LINQ不是魔术,T列表是一个带有缓冲空间的数组,带有一些额外的空间,以避免在添加项目时调整内部数组的大小。

所有抽象必须解决相同的问题,创建一个没有空插槽的数组,该插槽包含所有值并返回它们。

如果您需要灵活性,可以创建一个足够大的列表,您可以使用该列表然后执行此操作。否则使用数组并共享该线程安全对象。此外,新的Span有助于共享数据,而无需复制列表。

回答这个问题:

Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;

答案 12 :(得分:1)

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();

答案 13 :(得分:1)

使用扩展方法怎么样?例如:

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库运行。

答案 14 :(得分:1)

我同意Ed。 C#并不像VB对ReDim Preserve那样简单。没有集合,您将不得不将数组复制到更大的数组中。

答案 15 :(得分:0)

不幸的是,使用列表并不适用于所有情况。列表和数组实际上是不同的,并且不是100%可互换的。如果这是一个可接受的工作,将取决于具体情况。

答案 16 :(得分:0)

由于这个问题不满意提供的答案,我想补充一下这个答案:)

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;  
    } 
  }
 }
}

答案 17 :(得分:0)

为什么不尝试使用 Stringbuilder 类。它有.insert和.append等方法。您可以在此处详细了解:http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx

答案 18 :(得分:0)

//所以如果你有一个现有的数组

//我的快速修复将是

var tempList = originalArray.ToList();

tempList.Add(的newitem);

//现在只需用新的数组替换原始数组

originalArray = tempList.ToArray();

答案 19 :(得分: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;
    }