388 Stimmen

Wie kann ich einen Bereich von Array-Elementen in ein neues Array klonen?

Ich habe ein Array X mit 10 Elementen. Ich möchte ein neues Array erstellen, das alle Elemente aus X enthält, die bei Index 3 beginnen und bei Index 7 enden. Natürlich kann ich leicht eine Schleife schreiben, die das für mich erledigt, aber ich möchte meinen Code so sauber wie möglich halten. Gibt es eine Methode in C#, die dies für mich tun kann?

Etwas wie (Pseudo-Code):

Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)

Array.Copy passt nicht zu meinen Bedürfnissen . Die Elemente im neuen Array müssen Klone sein. Array.copy ist nur ein C-Stil memcpy Äquivalent, das ist nicht das, wonach ich suche.

507voto

Marc Gravell Punkte 970173

Sie könnten sie als Erweiterungsmethode hinzufügen:

public static T[] SubArray<T>(this T[] data, int index, int length)
{
    T[] result = new T[length];
    Array.Copy(data, index, result, 0, length);
    return result;
}
static void Main()
{
    int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int[] sub = data.SubArray(3, 4); // contains {3,4,5,6}
}

Update zum Klonen (was in der ursprünglichen Frage nicht offensichtlich war). Wenn Sie wirklich einen tiefen Klon wollen; so etwas wie:

public static T[] SubArrayDeepClone<T>(this T[] data, int index, int length)
{
    T[] arrCopy = new T[length];
    Array.Copy(data, index, arrCopy, 0, length);
    using (MemoryStream ms = new MemoryStream())
    {
        var bf = new BinaryFormatter();
        bf.Serialize(ms, arrCopy);
        ms.Position = 0;
        return (T[])bf.Deserialize(ms);
    }
}

Dazu müssen die Objekte serialisierbar sein ( [Serializable] o ISerializable ), obwohl. Sie können problemlos jeden anderen Serialisierer durch einen geeigneten ersetzen - XmlSerializer , DataContractSerializer , protobuf-net, etc.

Beachten Sie, dass Deep Clone ohne Serialisierung problematisch ist; insbesondere, ICloneable ist in den meisten Fällen schwer zu vertrauen.

350voto

Jon Skeet Punkte 1325502

Sie können verwenden Array.Copy(...) in das neue Array zu kopieren, nachdem Sie es erstellt haben, aber ich glaube nicht, dass es eine Methode gibt, die das neue Array erstellt y kopiert eine Reihe von Elementen.

Wenn Sie .NET 3.5 verwenden, können Sie könnte LINQ verwenden:

var newArray = array.Skip(3).Take(5).ToArray();

aber das wird etwas weniger effizient sein.

Voir diese Antwort auf eine ähnliche Frage nach Optionen für spezifischere Situationen.

77voto

Alex Black Punkte 13274

Haben Sie die Verwendung von ArraySegment ?

http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx

40voto

Andriy Volkov Punkte 18140

Wie ich sehe, wollen Sie nicht nur Referenzen kopieren, sondern auch klonen. In diesem Fall können Sie .Select um Array-Mitglieder auf ihre Klone zu projizieren. Zum Beispiel, wenn Ihre Elemente implementiert IClonable könnte man etwa so vorgehen:

var newArray = array.Skip(3).Take(5).Select(eachElement => eachElement.Clone()).ToArray();

Hinweis: Diese Lösung erfordert .NET Framework 3.5.

33voto

Volker Punkte 1535

Der folgende Code erledigt dies in einer Zeile:

// Source array
string[] Source = new string[] { "A", "B", "C", "D" };
// Extracting a slice into another array
string[] Slice = new List<string>(Source).GetRange(2, 2).ToArray();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X