C # .net'te var olan dizge dizisine yeni öğe nasıl eklenir?
Mevcut verileri korumam gerekiyor.
C # .net'te var olan dizge dizisine yeni öğe nasıl eklenir?
Mevcut verileri korumam gerekiyor.
Yanıtlar:
Dinamik olarak boyutlandırılmış bir diziye ihtiyacınız varsa bir Liste kullanırım:
List<string> ls = new List<string>();
ls.Add("Hello");
Bu bir çözüm olabilir;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
Ancak dinamik boyutlu diziler için de listeyi tercih ederim.
LINQ kullanarak:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
Bunu tek satırlık olduğu ve bir switch ifadesine, basit bir if-ifadesine veya argüman olarak geçirmeye çok uygun olduğu için kullanmayı seviyorum.
DÜZENLE:
Bazı insanlar new[] { newitem }, küçük, tek öğeli, geçici bir dizi oluşturduğu için sevmez . Burada, Enumerable.Repeatherhangi bir nesne oluşturmayı gerektirmeyen bir sürüm bulunmaktadır (en azından yüzeyde değil - .NET yineleyicileri muhtemelen tablonun altında bir grup durum makinesi nesnesi oluşturur).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
Ve dizinin asla nullbaşlamayacağından eminseniz, onu şu şekilde basitleştirebilirsiniz:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Sıralı bir koleksiyona öğe eklemek istiyorsanız List, muhtemelen başlamak için bir dizi değil, istediğiniz veri yapısı olduğuna dikkat edin.
Çok eski bir soru, ama yine de bunu eklemek istedim.
Tek satırlık bir ürün arıyorsanız, aşağıdaki kodu kullanabilirsiniz. Bir numaralandırılabilir ve "yeni" (soru ortaya çıktığından beri) başlatıcı sözdizimini kabul eden liste yapıcısını birleştirir.
myArray = new List<string>(myArray) { "add this" }.ToArray();
C # dizileri değişmezdir , örneğin string[],int[] . Bu, onları yeniden boyutlandıramayacağınız anlamına gelir. Yepyeni bir dizi oluşturmanız gerekiyor.
İşte Array.Resize kodu :
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;
}
}
Gördüğünüz gibi, yeni boyutta yeni bir dizi oluşturur, kaynak dizinin içeriğini kopyalar ve başvuruyu yeni diziye ayarlar. Bunun ipucu, ref , birinci parametrenin anahtar kelimesidir.
Yeni öğeler için dinamik olarak yeni yuvalar tahsis edebilen listeler vardır . Bu, örneğin Liste <T> . Bunlar değişmez diziler içerir ve gerektiğinde bunları yeniden boyutlandırır (List <T> bağlantılı bir liste uygulaması değildir!). ArrayList , Generics olmadan ( Object dizisi ile) aynı şeydir .
LinkedList <T> gerçek bir bağlantılı liste uygulamasıdır. Maalesef listeye yalnızca LinkListNode <T> öğeleri ekleyebilirsiniz, bu nedenle kendi liste öğelerinizi bu düğüm türüne sarmanız gerekir. Sanırım kullanımı nadirdir.
Aray.ResizeBir diziyi içeriğini kaybetmeden yeniden boyutlandırabileceğine inanıyorum . docs.microsoft.com/en-us/dotnet/api/…
Genel bir tür kullanarak bir uzantı yöntemi oluşturmak için LINQ tabanlı mantığını kullanarak @Stephen Chung tarafından sağlanan yanıtı genişletebilirsiniz.
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();
}
}
Daha sonra bu şekilde doğrudan dizi üzerinden çağırabilirsiniz.
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...
}
Kuşkusuz, AddRangeToArray () yöntemi, Concat () ile aynı işlevselliğe sahip olduğunuz için biraz abartılı görünmektedir, ancak bu şekilde, bitiş kodu, bunun tersine doğrudan dizi ile "çalışabilir":
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
Dizilerle çok çalışıyorsanız ve herhangi bir nedenle listelerle çalışmıyorsanız, bu genel türdeki genel dönüş yöntemi Addyardımcı olabilir
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;
}
Önerilen tüm yanıtlar, kaçınmak istediklerini söyledikleri şeyle aynı şeyi yapar, yeni bir dizi oluşturur ve ona yalnızca daha fazla ek yük kaybederek yeni bir giriş ekler. LINQ sihirli değildir, T listesi, öğeler eklendiğinde iç dizinin yeniden boyutlandırılmasını önlemek için fazladan boşluk içeren bir arabellek alanına sahip bir dizidir.
Tüm soyutlamaların aynı sorunu çözmesi, tüm değerleri tutan boş yuvaları olmayan bir dizi oluşturması ve bunları döndürmesi gerekir.
Esnekliğe ihtiyacınız varsa, geçmek için kullanabileceğiniz yeterince büyük bir liste oluşturabilir, sonra bunu yapın. başka bir dizi kullanır ve bu iş parçacığı güvenli nesneyi paylaşır. Ayrıca yeni Span, listeleri kopyalamak zorunda kalmadan verilerin paylaşılmasına yardımcı olur.
Soruyu cevaplamak için:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Dolayısıyla, mevcut bir diziniz varsa, benim hızlı düzeltmem
var tempList = originalArray.ToList();
tempList.Add(newitem);
Şimdi orijinal diziyi yenisiyle değiştirin
originalArray = tempList.ToArray();
Yeni bir Append<TSource>yöntem eklendiIEnumerable<TSource>.NET Framework 4.7.1 ve .NET Core 1.0'dan beri .
İşte nasıl kullanılacağı:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Öğeyi dizinin başına eklemek istiyorsanız, Prepend<TSource>bunun yerine yeni yöntemi kullanabileceğinizi unutmayın .
Bir uzatma yöntemi kullanmaya ne dersiniz? Örneğin:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
Örneğin:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Bunun Linq'in Uniion uzantısının (iki diziyi yeni bir dizide birleştirmek için kullanılır) bu davranışını taklit ettiğini ve Linq kitaplığının çalışması gerektiğini unutmayın.
Ed'e katılıyorum. C #, VB'nin ReDim Preserve ile yaptığı gibi bunu kolaylaştırmaz. Bir koleksiyon olmadan, diziyi daha büyük bir diziye kopyalamanız gerekir.
ReDim Preservebasitçe diziyi daha büyük bir diziye kopyalar. Mucizevi bir dizi yeniden boyutlandırma yoktur.
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;
}
Neden Stringbuilder sınıfını kullanmayı denemiyorsunuz ? .İnsert ve .append gibi yöntemleri vardır. Bununla ilgili daha fazla bilgiyi buradan okuyabilirsiniz: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Bu soru verilen cevaptan memnun olmadığından, bu cevabı eklemek istiyorum :)
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;
}
}
}
}