Mảng trong C# có kích thước cố định (fixed-size). Không thể "xóa" phần tử thực sự (giảm Length). Cách phổ biến: dịch chuyển phần tử (shift left) và bỏ qua phần tử cuối, hoặc tạo mảng mới.
Cách 1: Dịch chuyển trong cùng mảng (In-place shift)
Áp dụng khi không cần giữ Length cũ, chấp nhận phần tử cuối bị "rác" (giá trị cũ).
using System;
class Program
{
static void Main()
{
int[] arr = { 35, 50, 55, 77, 98 };
int pos = 2; // Vị trí 1-based (phần tử thứ 2 = 50)
Console.WriteLine("Trước: " + string.Join(", ", arr));
// Dịch trái từ pos-1 (0-based) đến Length-2
for (int i = pos - 1; i < arr.Length - 1; i++)
arr[i] = arr[i + 1];
// Phần tử cuối giờ là "rác" (98), Length vẫn = 5
Console.WriteLine("Sau (Length không đổi): " + string.Join(", ", arr));
Console.WriteLine($"Phần tử hợp lệ: {string.Join(", ", arr[0..(arr.Length-1)])}"); // Range C# 8+
}
}
Cách 2: Tạo mảng mới (Khuyên dùng - an toàn, rõ ràng)
using System;
using System.Linq; // Cần cho ToArray()
class Program
{
static T[] RemoveAt<T>(T[] source, int index)
{
if (index < 0 || index >= source.Length)
throw new ArgumentOutOfRangeException(nameof(index));
T[] result = new T[source.Length - 1];
Array.Copy(source, 0, result, 0, index); // Copy phần trước
Array.Copy(source, index + 1, result, index, source.Length - index - 1); // Copy phần sau
return result;
}
static void Main()
{
int[] arr = { 35, 50, 55, 77, 98 };
Console.WriteLine("Trước: " + string.Join(", ", arr));
arr = RemoveAt(arr, 1); // Xóa index 1 (giá trị 50)
Console.WriteLine("Sau: " + string.Join(", ", arr)); // Length = 4
}
}
Cách 3: Dùng List<T> (Khuyên dùng nhất cho thực tế)
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var list = new List<int> { 35, 50, 55, 77, 98 };
Console.WriteLine("Trước: " + string.Join(", ", list));
list.RemoveAt(1); // Xóa index 1
// hoặc list.Remove(50); // Xóa theo giá trị (phần tử đầu tiên)
Console.WriteLine("Sau: " + string.Join(", ", list));
}
}
So sánh
| Cách | Độ phức tạp | Thay đổi Length | Hiệu năng | Khuyên dùng |
|---|---|---|---|---|
| Shift in-place | O(n) | Không (Length giữ nguyên) | Nhanh, ít alloc | Hiếm (embedded, fixed buffer) |
| Tạo mảng mới | O(n) | Có (Length - 1) | Alloc mới | Khi phải dùng array |
List<T> | O(n) | Tự động | Tối ưu nội bộ | Luôn ưu tiên |
Kết luận: Trong C# hiện đại, hãy dùng List<T> cho tập hợp cần thêm/xóa. Chỉ dùng mảng khi cần hiệu năng cực đại, interop, hoặc API yêu cầu mảng.