Làm cách nào để thêm mục mới trong mảng chuỗi hiện có trong C # .net?
Tôi cần phải bảo tồn dữ liệu hiện có.
Làm cách nào để thêm mục mới trong mảng chuỗi hiện có trong C # .net?
Tôi cần phải bảo tồn dữ liệu hiện có.
Câu trả lời:
Tôi sẽ sử dụng Danh sách nếu bạn cần một mảng có kích thước động:
List<string> ls = new List<string>();
ls.Add("Hello");
Đó có thể là một giải pháp;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
Nhưng đối với mảng kích thước động, tôi cũng muốn liệt kê.
Sử dụng LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
Tôi thích sử dụng điều này vì nó là một lớp lót và rất thuận tiện để nhúng vào câu lệnh chuyển đổi, câu lệnh if đơn giản hoặc truyền làm đối số.
BIÊN TẬP:
Một số người không thích new[] { newitem }
vì nó tạo ra một mảng nhỏ, một mục, tạm thời. Đây là một phiên bản sử dụng Enumerable.Repeat
không yêu cầu tạo bất kỳ đối tượng nào (ít nhất là không phải trên bề mặt - Trình lặp .NET có thể tạo ra một loạt các đối tượng máy trạng thái dưới bảng).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
Và nếu bạn chắc chắn rằng mảng không bao giờ null
bắt đầu, bạn có thể đơn giản hóa nó thành:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Lưu ý rằng nếu bạn muốn thêm các mục vào một bộ sưu tập theo thứ tự, List
có thể là cấu trúc dữ liệu bạn muốn, không phải là một mảng để bắt đầu.
Câu hỏi rất cũ, nhưng vẫn muốn thêm điều này.
Nếu bạn đang tìm kiếm một lớp lót, bạn có thể sử dụng mã dưới đây. Nó kết hợp hàm tạo danh sách chấp nhận cú pháp khởi tạo vô số và "mới" (kể từ khi đặt câu hỏi).
myArray = new List<string>(myArray) { "add this" }.ToArray();
Mảng trong C # là bất biến , ví dụ string[]
, int[]
. Điều đó có nghĩa là bạn không thể thay đổi kích thước chúng. Bạn cần tạo một mảng hoàn toàn mới.
Đây là mã cho 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;
}
}
Như bạn có thể thấy nó tạo ra một mảng mới với kích thước mới, sao chép nội dung của mảng nguồn và đặt tham chiếu đến mảng mới. Gợi ý cho điều này là từ khóa ref cho tham số đầu tiên.
Có những danh sách có thể tự động phân bổ các vị trí mới cho các mục mới. Đây là ví dụ Danh sách <T> . Chúng chứa các mảng bất biến và thay đổi kích thước chúng khi cần (Danh sách <T> không phải là triển khai danh sách được liên kết!). ArrayList là điều tương tự không có Generics (với mảng Object ).
LinkedList <T> là một triển khai danh sách liên kết thực sự. Thật không may, bạn chỉ có thể thêm các phần tử LinkListNode <T> vào danh sách, vì vậy bạn phải bọc các phần tử danh sách của riêng bạn vào loại nút này. Tôi nghĩ rằng việc sử dụng nó là không phổ biến.
Aray.Resize
có thể thay đổi kích thước một mảng mà không mất nội dung của nó. docs.microsoft.com/en-us/dotnet/api/ từ
Bạn có thể mở rộng câu trả lời do @Stephen Chung cung cấp bằng cách sử dụng logic dựa trên LINQ của anh ấy để tạo phương thức mở rộng bằng cách sử dụng loại 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();
}
}
Sau đó bạn có thể gọi nó trực tiếp trên mảng như thế này.
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...
}
Phải thừa nhận rằng phương thức AddRangeToArray () có vẻ hơi quá mức vì bạn có cùng chức năng với Concat () nhưng theo cách này, mã kết thúc có thể "hoạt động" với mảng trực tiếp trái ngược với điều này:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
nếu bạn đang làm việc rất nhiều với các mảng và không liệt kê vì một số lý do, phương thức trả về chung được gõ này Add
có thể giúp ích
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;
}
Tất cả các câu trả lời được đề xuất thực hiện giống như những gì họ nói họ muốn tránh, tạo một mảng mới và thêm một mục mới trong đó chỉ với việc mất thêm chi phí. LINQ không phải là phép thuật, danh sách T là một mảng có không gian bộ đệm có thêm một số không gian để tránh thay đổi kích thước mảng bên trong khi các mục được thêm vào.
Tất cả các khái niệm trừu tượng phải giải quyết cùng một vấn đề, tạo một mảng không có các ô trống chứa tất cả các giá trị và trả về chúng.
Nếu bạn cần sự linh hoạt, bạn có thể tạo một danh sách đủ lớn để bạn có thể sử dụng để vượt qua, sau đó làm điều đó. khác sử dụng một mảng và chia sẻ đối tượng an toàn luồng. Ngoài ra, Span mới giúp chia sẻ dữ liệu mà không phải sao chép danh sách xung quanh.
Để trả lời câu hỏi:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Vì vậy, nếu bạn có một mảng hiện có, sửa chữa nhanh của tôi sẽ là
var tempList = originalArray.ToList();
tempList.Add(newitem);
Bây giờ chỉ cần thay thế mảng ban đầu bằng mảng mới
originalArray = tempList.ToArray();
Một Append<TSource>
phương thức mới đã được thêm vàoIEnumerable<TSource>
kể từ .NET Framework 4.7.1 và .NET Core 1.0.
Đây là cách sử dụng nó:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Lưu ý rằng nếu bạn muốn thêm phần tử vào đầu mảng, bạn có thể sử dụng Prepend<TSource>
phương thức mới thay thế.
Điều gì về việc sử dụng một phương pháp mở rộng? Ví dụ:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
ví dụ:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Lưu ý điều này bắt chước hành vi này của tiện ích mở rộng Uniion của Linq (được sử dụng để kết hợp hai mảng thành một mảng mới) và yêu cầu thư viện Linq hoạt động.
Tôi đồng ý với Ed. C # không làm điều này dễ dàng như cách VB làm với ReDim Preserve. Nếu không có bộ sưu tập, bạn sẽ phải sao chép mảng thành một bộ lớn hơn.
ReDim Preserve
chỉ cần sao chép mảng thành một lager. Không có thay đổi kích thước mảng kỳ diệu.
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();
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;
}
Tại sao không thử sử dụng lớp Stringbuilder . Nó có các phương thức như .insert và .append. Bạn có thể đọc thêm về nó ở đây: http://msdn.microsoft.com/en-us/l Library / 2839d5h5 (v = vs.71) .aspx
Vì câu hỏi này không hài lòng với câu trả lời được cung cấp, tôi muốn thêm câu trả lời này :)
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;
}
}
}
}