【发布时间】:2010-06-30 03:01:39
【问题描述】:
我正在从源中读取数据作为数组。一个[n]
我需要在数组中再添加一个元素。
获得数组后,我创建一个容量为 n+1 的新数组,并将所有元素复制到新数组中,并将新元素作为数组的最后一个元素。
我能做到。
有没有更好的方法来做到这一点?尤其是 Linq?
【问题讨论】:
-
请不要在标题中添加“C#”之类的标签。只需将标签留在标签中,这是标签所属的地方。
我正在从源中读取数据作为数组。一个[n]
我需要在数组中再添加一个元素。
获得数组后,我创建一个容量为 n+1 的新数组,并将所有元素复制到新数组中,并将新元素作为数组的最后一个元素。
我能做到。
有没有更好的方法来做到这一点?尤其是 Linq?
【问题讨论】:
您所描述的确实是唯一的方法。数组不能在 .NET 中调整大小,因此我们必须分配一个新数组并将旧数组复制到其中。例如,Array.Resize 就是这样工作的。 LINQ 在这里并不是真正的帮助,如果是的话,它只是将现有数组投影到一个新数组中——这正是我们刚刚描述的。
如果您发现需要经常调整数组大小,您应该考虑使用ArrayList,或者如果可能,使用强类型List<T>。
编辑:
如果您只是从某种您无法控制的方法中获取一个数组,但在您的代码中您可以使用 IEnumerable<T> 代替,您可以使用 LINQ 进行延迟枚举并节省额外的数组分配:
var mySequence = originalArray.Concat(new[]{myobj});
//snip
foreach(var item in mySequence)
{
//do stuff
}
只有在调用ToArray() 时才会产生额外开销。否则,我们只是简单地对原始数组进行一次枚举,然后在最后偷偷添加额外的项目。
【讨论】:
Add 方法是什么?
如果要使用 LINQ 将数组放在一起,可以使用 Concat:
var combined = array1.Concat(new[] { element }).ToArray();
但是,您现在正在为您的集合创建许多不同的数组。更好的选择是只使用一个列表。它将由单个数组支持并为您自动扩展。
【讨论】:
使用C# yield 可以让您返回您的阵列等,而无需分配额外的存储空间。在产生原始数组的每个元素后,您可以像这样轻松地滑入任何额外的元素:
IEnumerable<int> GetEverything() {
// first return the entire original array
foreach(int num in arrNumbers)
yield return num;
// then slip in extra element at the end
yield return 5; // yield even more elements if you want...
}
然后你可以像这样使用它:
foreach (int n in GetEverything())
Console.WriteLine(n);
在这种情况下没有必要退出 LINQ,因为 yield 语句很简单并且完全适合您的需要。
【讨论】:
你可以只使用数组来初始化一个列表。
var stuff = new List<object>( a );
stuff.Add( moreStuff );
【讨论】:
SomeType替换object
您可以为此使用Array.Resize:
http://msdn.microsoft.com/en-us/library/bb348051.aspx
它基本上可以完成您手动完成的工作,但更整洁。
如果您定期向数组中添加多个元素,我建议您移至列表,因为这样插入效率更高。
【讨论】:
改用List<T>,并调用myList.Add(item)
编辑:如果您的意思是以数组的形式获取数据(而不是将数据读入其中),请使用 List 的构造函数从数组中复制。
【讨论】:
您可以使用 ToArray 和 ToList Linq 命令。
这是一个通用方法,它将返回一个新数组,该数组将是原始数组和新项目的副本。
public static T[] AddItem<T>( T[] array, T item )
{
List<T> list = array.ToList();
list.Add( item );
return list.ToArray();
}
这是一个将项目添加到数组中的通用扩展方法。 (该数组将是内存中的一个新数组,因此可能会产生副作用)。
public static void AddItem<T>( this T[] array, T item )
{
List<T> list = array.ToList();
list.Add( item );
array = list.ToArray(); /* Untested, this may not compile! */
}
【讨论】:
this 参数通过引用传递,这让我感到惊讶。
如果你必须使用相同类型的数组 {ArrayVar1,ArrayVar2}
,你可以使用类似的东西var arrayList = ArrayVar1.ToList();
arrayList.AddRange(ArrayVar2); // or for single element use arrayList.Add(Var2);
ArrayVar1=arrayList.ToArray();
【讨论】:
使用数组方法 Resize 和 ConstrinedCopy 的示例。无需制作额外的数组。
Filter[] filterA = new Filter[] {
new Filter() { field = "trans_date", Data = "2018-01-01", Op = "gt" }
, new Filter() { field = "trans_date", Data = "2018-01-02", Op = "gt" }
, new Filter() { field = "trans_date", Data = "2018-01-03", Op = "gt" }
};
Filter[] filterB = new Filter[] {
new Filter() { field = "trans_date", Data = "2018-01-04", Op = "gt" }
, new Filter() { field = "trans_date", Data = "2018-01-05", Op = "gt" }
};
//resizing the original array to hold all the new elements.
Array.Resize(ref filterA, filterA.Length + filterB.Length);
//take the items from filterB and place them in filterA
Array.ConstrainedCopy(filterB, 0, filterA, 3, 2);
【讨论】: