web-dev-qa-db-ger.com

Fügen Sie ein neues Element in einem vorhandenen Array in c # .net hinzu

Wie füge ich ein neues Element in einem vorhandenen String-Array in C # .net hinzu?

Ich muss die vorhandenen Daten erhalten.

112
Nirmal

Ich würde eine Liste verwenden, wenn Sie ein Array mit dynamischer Größe benötigen:

List<string> ls = new List<string>();
ls.Add("Hello");
111
Ed S.

Das könnte eine Lösung sein;

Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"

Aber für ein Array mit dynamischer Größe würde ich auch die Liste bevorzugen.

87
Ali Ersöz

Verwendung von LINQ:

arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();

Ich mag es, dies zu verwenden, da es sich um einen Einzeiler handelt, der sehr bequem in eine switch-Anweisung, eine einfache if-Anweisung oder als Argument übergeben werden kann.

BEARBEITEN:

Einige Leute mögen new[] { newitem } nicht, weil dadurch ein kleines temporäres Array mit einem Element erstellt wird. Hier ist eine Version mit Enumerable.Repeat, für die kein Objekt erstellt werden muss (zumindest nicht auf der Oberfläche - .NET-Iteratoren erstellen wahrscheinlich eine Reihe von Zustandsmaschinenobjekten unter der Tabelle).

arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();

Und wenn Sie sicher sind, dass das Array zu Beginn nie null ist, können Sie es vereinfachen:

arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();

Wenn Sie einer geordneten Sammlung Elemente hinzufügen möchten, ist List wahrscheinlich die gewünschte Datenstruktur und nicht ein Array, mit dem Sie beginnen möchten.

48
Stephen Chung

Arrays in C # sind unveränderlich , z. string[], int[]. Das bedeutet, dass Sie die Größe nicht ändern können. Sie müssen ein brandneues Array erstellen.

Hier ist der Code für 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;
    }
}

Wie Sie sehen, wird ein neues Array mit der neuen Größe erstellt, der Inhalt des Quellarrays wird kopiert und der Verweis auf das neue Array festgelegt. Der Hinweis hierfür ist das Schlüsselwort ref für den ersten Parameter.

Es gibt Listen, die neue Slots dynamisch zuordnen können für neue Artikel. Dies ist z.B. List <T>. Diese enthalten unveränderliche Arrays und passen deren Größe bei Bedarf an (Liste <T> ist keine Implementierung einer verknüpften Liste!). ArrayList ist dasselbe ohne Generics (mit Object -Array).

LinkedList <T> ist eine echte Implementierung einer verknüpften Liste. Leider können Sie der Liste nur LinkListNode <T> -Elemente hinzufügen. Sie müssen also Ihre eigenen Listenelemente in diesen Knotentyp einschließen. Ich denke, seine Verwendung ist ungewöhnlich.

23
artur02

Sehr alte Frage, wollte aber noch hinzufügen.

Wenn Sie nach einem Einzeiler suchen, können Sie den nachstehenden Code verwenden. Es kombiniert den Listenkonstruktor, der eine Aufzählungszeichen und die (seit der Frage aufgeworfene) neue Initialisierungssyntax akzeptiert.

myArray = new List<string>(myArray) { "add this" }.ToArray();
21
 Array.Resize(ref youur_array_name, your_array_name.Length + 1);
 your_array_name[your_array_name.Length - 1] = "new item";
19
tmania

Sie können die Antwort von @Stephen Chung erweitern, indem Sie mit seiner LINQ-basierten Logik eine Erweiterungsmethode mit einem generischen Typ erstellen.

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();
    }

}

Sie können es so direkt auf dem Array aufrufen.

    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...
    }

Zwar scheint die AddRangeToArray () - Methode etwas übertrieben zu sein, da Sie dieselbe Funktionalität wie Concat () haben, aber auf diese Weise kann der Endcode direkt mit dem Array "arbeiten".

options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
7
dblood

wenn Sie häufig mit Arrays und nicht mit Listen arbeiten, kann diese generische generierte Rückgabemethode Add hilfreich sein

    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;
    }
5
stackuser83

Es ist besser, Array unveränderlich und fest zu halten.

sie können Add mit Extension Method und IEnumerable.Concat() simulieren.

public static class ArrayExtensions
    {
        public static string[] Add(this string[] array, string item)
        {
            return array.Concat(new[] {item}).ToArray();
        }
    }
3
Soren

Die Verwendung einer Liste wäre die beste Option für die Speicherverwaltung.

2
Axxelsian

Alle vorgeschlagenen Antworten entsprechen dem, was sie vermeiden möchten, indem sie ein neues Array erstellen und einen neuen Eintrag hinzufügen, der nur mit mehr Aufwand verbunden ist. LINQ ist keine Zauberei, Liste von T ist ein Array mit einem Pufferbereich mit zusätzlichem Speicherplatz, um die Größe des inneren Arrays beim Hinzufügen von Elementen zu vermeiden. 

Alle Abstraktionen müssen dasselbe Problem lösen. Erstellen Sie ein Array ohne leere Slots, die alle Werte enthalten, und geben Sie sie zurück. 

Wenn Sie die Flexibilität benötigen, können Sie eine ausreichend große Liste erstellen, die Sie zum Weitergeben verwenden können. Verwenden Sie andernfalls ein Array und geben Sie das Thread-sichere Objekt frei. Der neue Span hilft auch dabei, Daten gemeinsam zu nutzen, ohne die Listen herum kopieren zu müssen. 

Um die Frage zu beantworten:

Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
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();
1

Ich stimme Ed zu. C # macht dies nicht so einfach wie VB mit ReDim Preserve. Ohne Sammlung müssen Sie das Array in ein größeres kopieren.

1
harpo

Was ist mit einer Erweiterungsmethode? Zum Beispiel:

public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
    return source.Union(new TSource[] { item });
}

zum Beispiel:

string[] sourceArray = new []
{
    "foo",
    "bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);

Beachten Sie, dass dies das Verhalten der Linq-Uniion-Erweiterung (die zum Kombinieren von zwei Arrays zu einem neuen Array verwendet wird) imitiert und dass die Linq-Bibliothek funktionieren muss.

1
William

// Also wenn du ein Array hast

// Meine schnelle Lösung wird sein

var tempList = originalArray.ToList ();

tempList.Add (neues Element);

// Ersetzen Sie jetzt einfach das ursprüngliche Array durch das neue

originalArray = tempList.ToArray ();

0
Adi_Pithwa

Warum probieren Sie es nicht mit der Klasse Stringbuilder aus. Es hat Methoden wie .insert und .append. Weitere Informationen hierzu finden Sie hier: http://msdn.Microsoft.com/de-de/library/2839d5h5(v=vs.71).aspx

0
aevanko
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;
    }
0
Dave Blake

Da diese Frage mit der angegebenen Antwort nicht zufrieden ist, möchte ich diese Antwort hinzufügen :)

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;  
    } 
  }
 }
}
0
Saif

Leider funktioniert die Verwendung einer Liste nicht in allen Situationen. Eine Liste und ein Array unterscheiden sich tatsächlich und sind nicht zu 100% austauschbar. Es wäre von den Umständen abhängig, ob dies eine akzeptable Lösung wäre.

0
JAR