Come aggiungere un nuovo elemento nell'array di stringhe esistente in C # .net?
Devo conservare i dati esistenti.
Come aggiungere un nuovo elemento nell'array di stringhe esistente in C # .net?
Devo conservare i dati esistenti.
Risposte:
Vorrei utilizzare un elenco se hai bisogno di un array di dimensioni dinamiche:
List<string> ls = new List<string>();
ls.Add("Hello");
Potrebbe essere una soluzione;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
Ma per array di dimensioni dinamiche preferirei anche l'elenco.
Utilizzando LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
Mi piace usare questo in quanto è un singolo e molto comodo da incorporare in un'istruzione switch, una semplice istruzione if o passare come argomento.
MODIFICARE:
Ad alcune persone non piace new[] { newitem }perché crea un array temporaneo di piccole dimensioni con un solo elemento. Ecco una versione Enumerable.Repeatche utilizza che non richiede la creazione di alcun oggetto (almeno non in superficie - gli iteratori .NET probabilmente creano un gruppo di oggetti macchina a stati sotto la tabella).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
E se sei sicuro che l'array non nulldebba mai iniziare, puoi semplificarlo per:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Si noti che se si desidera aggiungere elementi a una raccolta ordinata, Listè probabilmente la struttura di dati desiderata, non un array con cui iniziare.
Domanda molto vecchia, ma volevo ancora aggiungere questo.
Se stai cercando un one-liner, puoi usare il codice qui sotto. Combina il costruttore di elenchi che accetta una sintassi enumerabile e "nuova" (dalla domanda sollevata).
myArray = new List<string>(myArray) { "add this" }.ToArray();
Array in C # sono immutabili , ad esempio string[], int[]. Ciò significa che non puoi ridimensionarli. Devi creare un nuovo array.
Ecco il codice per 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;
}
}
Come puoi vedere, crea un nuovo array con le nuove dimensioni, copia il contenuto dell'array di origine e imposta il riferimento al nuovo array. Il suggerimento per questo è la parola chiave ref per il primo parametro.
Esistono elenchi che possono allocare dinamicamente nuovi slot per nuovi elementi. Questo è ad esempio Elenco <T> . Questi contengono array immutabili e li ridimensionano quando necessario (Elenco <T> non è un'implementazione dell'elenco collegato!). ArrayList è la stessa cosa senza Generics (con array di oggetti ).
LinkedList <T> è una vera implementazione dell'elenco dei collegamenti. Sfortunatamente puoi aggiungere solo elementi LinkListNode <T> all'elenco, quindi devi avvolgere i tuoi elementi di elenco in questo tipo di nodo. Penso che il suo uso sia raro.
Aray.Resizepossa ridimensionare un array senza perdere il suo contenuto. docs.microsoft.com/en-us/dotnet/api/…
Puoi espandere la risposta fornita da @Stephen Chung usando la sua logica basata su LINQ per creare un metodo di estensione usando un tipo generico.
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();
}
}
È quindi possibile chiamarlo direttamente sull'array in questo modo.
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...
}
Certo, il metodo AddRangeToArray () sembra un po 'eccessivo poiché hai la stessa funzionalità con Concat () ma in questo modo il codice finale può "funzionare" con l'array direttamente al contrario:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
se si lavora molto con array e non elenchi per qualche motivo, questo metodo generico restituito tipizzato Addpotrebbe essere utile
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;
}
Tutte le risposte proposte fanno lo stesso di quello che dicono che vorrebbero evitare, creando un nuovo array e aggiungendo una nuova voce in esso solo con un overhead maggiore perso. LINQ non è magico, l'elenco di T è un array con uno spazio buffer con un po 'di spazio in più per evitare di ridimensionare l'array interno quando vengono aggiunti elementi.
Tutte le astrazioni devono risolvere lo stesso problema, creare un array senza slot vuoti che contenga tutti i valori e li restituisca.
Se hai bisogno della flessibilità, puoi creare un elenco abbastanza grande che puoi usare per passare, quindi fallo. altrimenti usa un array e condividi quell'oggetto thread-safe. Inoltre, il nuovo Span aiuta a condividere i dati senza dover copiare gli elenchi.
Per rispondere alla domanda:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Quindi, se hai un array esistente, la mia soluzione rapida sarà
var tempList = originalArray.ToList();
tempList.Add(newitem);
Ora basta sostituire l'array originale con quello nuovo
originalArray = tempList.ToArray();
È Append<TSource>stato aggiunto un nuovo metodoIEnumerable<TSource> partire da .NET Framework 4.7.1 e .NET Core 1.0 .
Ecco come usarlo:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Se si desidera aggiungere l'elemento all'inizio dell'array, è possibile utilizzare invece il nuovo Prepend<TSource>metodo.
Che dire dell'utilizzo di un metodo di estensione? Per esempio:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
per esempio:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Nota: questo imita questo comportamento dell'estensione Uniion di Linq (usato per combinare due array in uno nuovo) e richiedeva il funzionamento della libreria Linq.
Sono d'accordo con Ed. C # non lo rende facile come VB con ReDim Preserve. Senza una raccolta, dovrai copiare l'array in uno più grande.
ReDim Preservecopia semplicemente l'array in uno più chiaro. Non esiste un ridimensionamento miracoloso dell'array.
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;
}
Perché non provare usando la classe Stringbuilder . Ha metodi come .insert e .append. Puoi leggere di più qui: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Poiché questa domanda non è soddisfatta della risposta fornita, vorrei aggiungere questa risposta :)
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;
}
}
}
}