2010-12-09 7 views
0

Nehmen wir an, ich habe eine long[] namens IDs mit ein paar Elementen im Array.C#: Spleißen Array

Was ist der einfachste Weg, um ein neues Element in einem bestimmten Index zu spleißen/einzufügen?

Im Moment mache ich das, und ich glaube nicht, es ist optimal:

long[] IDs = ...; 

var IDsList = IDs.ToList(); 
IDsList.Insert(newId, indexToInsertAt); 

IDs = IDsList.ToArray(); 

Es gibt nichts, eingebaut in die Array Klasse ?! Das kommt mir sehr merkwürdig vor, da es aus der JavaScript-Welt [].splice() stammt.

+6

Gibt es Gründe, Sie verwenden ein Array über eine Liste ? –

+0

Es fiel mir seltsam, auch von PHP zu kommen, aber was Sie haben, ist, was ich in C verwenden würde # – Dinah

+1

Es ist nichts in die Array-Klasse eingebaut, denn das ist, was die Liste Klasse für –

Antwort

11

Verwenden Sie anstelle des Arrays eine List<long>, da Sie Einfügungen vornehmen müssen.

+0

ist Hmm, anscheinend war das nicht klar : Das Argument, mit dem ich arbeiten muss (definiert durch eine Schnittstelle), ist lang []. – AgileMeansDoAsLittleAsPossible

+0

@AgileMeansDoAsLittleAsPossible: Warte, bist du das OP? Scheint, du hast mehrere Identitäten ... –

+0

Hmm, eine Schnittstelle kann keine Felder angeben. Sie können die Größe eines Arrays, das als Methodenargument übergeben wurde, nicht ändern, es sei denn, es wird * ref * deklariert. –

-1

könnten Sie mit versuchen

IDs.SetValue(newId, indexToInsertAt); 

More here

+0

Aber ich bin mit Aaron und Tim Robinson, benutze eine Liste und Problem gelöst. – FelixMM

+3

Das fügt kein Element ein, sondern ersetzt ein Element. Wenn das alles wäre, was er tun wollte, würde er 'IDs [indexToInsertAt] = newId' schreiben. –

6

Es könnte ein wenig seltsam erscheinen, aber es blieb wahrscheinlich aus Entwicklern zu verhindern, dass das Schreiben von Code zu leicht mit schlechter Leistung. (Wenn Sie ein neues Element in die Mitte einfügen, möchten Sie wahrscheinlich eine veränderbare Sammlung wie List<T>.) Die einzige Möglichkeit zum Einfügen in eine Sammlung mit fester Größe wie Array ist das Kopieren der Inhalte der Sammlung in eine neue Sammlung und legte den Artikel dort. Offensichtlich ist dies nicht die beste Idee, wenn Sie viele Einfügungen durchführen.

Wenn die Verwendung eines T[] Array außerhalb Ihrer Kontrolle, und das Einsetzen ist notwendig, um das Array zu kopieren, sich zumindest vorzuziehen, um den Code, die Sie haben, wie es Ihnen zwei teure Operationen erspart: eine Kopie und eine Insertion Dies erfordert, dass potenziell viele Elemente um einen Index "verschoben" werden. (Ihre aktuelle Lösung kopiert den Inhalt des long[] in eine List<long>, fügt dann ein Element in diesem List<long>, dann Kopien, die List<long>zurück in eine neue long[].)

In diesem Fall (die Wahl eines T[] ist nicht verhandelbar), könnten Sie eine Erweiterungsmethode zu tun, was ich oben beschrieben habe. Auf diese Weise haben Sie zumindest ein wiederverwendbares Stück Code für Szenarien, wenn Sie dieses Verhalten benötigen tun. Etwas wie:

public static class ArrayHelper 
{ 
    public static T[] Insert<T>(this T[] source, int index, T item) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 

     if (index < 0 || index > source.Length) 
     { 
      throw new ArgumentOutOfRangeException("index"); 
     } 

     // Allocate a new array with enough space for one more item. 
     T[] result = new T[source.Length + 1]; 

     // Copy all elements before the insertion point. 
     for (int i = 0; i < index; ++i) 
     { 
      result[i] = source[i]; 
     } 

     // Insert the new value. 
     result[index] = item; 

     // Copy all elements after the insertion point. 
     for (int i = index; i < source.Length; ++i) 
     { 
      result[i + 1] = source[i]; 
     } 

     return result; 
    } 
} 

Beachten Sie, dass die oben ist deutlich effizienter als das, was Sie jetzt haben, da sie nur die äquivalent eine vollständige Array Kopie eine Zeit (nicht zweimal) ausführen muss, und es auch doesn Es bedarf keiner Zwischenschaltung von Elementen.

Verbrauch:

int[] numbers = new int[] { 2, 3, 4 }; 
numbers = numbers.Insert(0, 1); 

foreach (int number in numbers) 
{ 
    Console.WriteLine(number); 
} 

Ausgang:

 
1 
2 
3 
4 
1

Mit etwas Ähnliches zu tun, hier ist was ich habe kommen mit, ähnlich wie Dan Tao:

T[] newArr = new T[oldArr.Length+1]; 

//copy first part of the array, starting with newArr[0] <- oldArr[0], up to the insertion point 
System.Array.Copy(oldArr, 0, newArr, 0, insertIndex, insertIndex); 

//insert new element 
newArr[insertIndex] = spliceElem; 

//copy the rest of the array, from newArr[insert+1] <- oldArr[insert] to the end 
System.Array.Copy(oldArr, insertIndex, newArr, insertIndex + 1, oldArr.Length-insertIndex); 
return newArr;