int[] x = new int [] { 1, 2, 3};
int[] y = new int [] { 4, 5 };
int[] z = // your answer here...
Debug.Assert(z.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
Im Moment benutze ich
int[] z = x.Concat(y).ToArray();
Gibt es eine einfachere oder effizientere Methode?
Antworten:
quelle
params
Parameter mit variabler Anzahl .System.IO.Directory.GetFiles()
gibt ein Array von Strings zurück.Versuche dies:
quelle
List<int> list = new List<int>(x);
Sie könnten eine Erweiterungsmethode schreiben:
Dann:
quelle
Copy
schneller alsCopyTo
? Möchtest du das näher erläutern?Ich habe mich für eine allgemeinere Lösung entschieden, mit der eine beliebige Menge eindimensionaler Arrays desselben Typs verkettet werden kann. (Ich habe 3+ gleichzeitig verkettet.)
Meine Funktion:
Und Verwendung:
quelle
params T[][]
,this T[][]
um es zu einer Erweiterung zu machen.Das ist es:
quelle
int[] result = array1.ToList().Concat(array2.ToList()).toArray();
Sie können Concat nicht direkt auf Arrays anwenden, glaube ichtoArray()
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
int[] result = ?
, Sie verstecken das Problem Ihrer Antwort hinter Ihrem,var
dass Ihr Ergebnis sein wirdIEnumerable<int>
, nichtint[]
. (Einer der Gründe, warum ichvar
bei Methodenrückgaben nicht mag ).ToArray()
Aufruf gibt dieser Code kein tatsächliches Array zurück, sodass es sich auch um eine falsche Antwort handelt.Sie können den ToArray () -Aufruf am Ende abbrechen. Gibt es einen Grund, warum es nach dem Aufruf von Concat ein Array sein muss?
Durch Aufrufen von Concat wird ein Iterator über beide Arrays erstellt. Es wird kein neues Array erstellt, sodass Sie nicht mehr Speicher für ein neues Array verwendet haben. Wenn Sie ToArray aufrufen, erstellen Sie tatsächlich ein neues Array und belegen den Speicher für das neue Array.
Wenn Sie also nur einfach über beide iterieren müssen, rufen Sie einfach Concat an.
quelle
Ich weiß, dass das OP nur leicht neugierig auf die Leistung war. Diese größeren Arrays erhalten möglicherweise ein anderes Ergebnis (siehe @kurdishTree). Und dass es normalerweise keine Rolle spielt (@ jordan.peoples). Trotzdem war ich neugierig und verlor deshalb den Verstand (wie @TigerShark erklärte) .... Ich meine, ich habe einen einfachen Test geschrieben, der auf der ursprünglichen Frage basiert .... und allen Antworten ....
Das Ergebnis war:
Wirf deine eigenen Gewinne.
quelle
CopyTo
am schnellsten und ~ 3x schneller als istRoll your own
.Seien Sie vorsichtig mit der
Concat
Methode. Die Post- Array-Verkettung in C # erklärt Folgendes :Wird für große Arrays ineffizient sein.
Concat
Dies bedeutet, dass die Methode nur für Arrays mit mittlerer Größe (bis zu 10000 Elemente) gilt.quelle
quelle
Effizientere (schneller) zu verwenden ,
Buffer.BlockCopy
überArray.CopyTo
,Ich habe ein einfaches Testprogramm geschrieben, das "den Jitter erwärmt", im Release-Modus kompiliert und ohne angeschlossenen Debugger auf meinem Computer ausgeführt.
Für 10.000.000 Iterationen des Beispiels in der Frage
Wenn ich die Testarrays auf zwei Sequenzen von 0 bis 99 ändere, erhalte ich ähnliche Ergebnisse.
Aus diesen Ergebnissen kann ich behaupten, dass die
CopyTo
undBlockCopy
Methoden wesentlich effizienter sind alsConcat
und darüber hinaus, wenn Leistung ein ZielBlockCopy
ist, Wert über habenCopyTo
.Um diese Antwort einzuschränken, wählen Sie die Methode, die Sie am einfachsten finden, wenn die Leistung keine Rolle spielt oder nur wenige Iterationen stattfinden.
Buffer.BlockCopy
bietet ein Dienstprogramm für die Typkonvertierung, das über den Rahmen dieser Frage hinausgeht.quelle
Späte Antwort :-).
quelle
Die effizienteste Struktur in Bezug auf RAM (und CPU), um das kombinierte Array zu halten, wäre eine spezielle Klasse, die IEnumerable implementiert (oder wenn Sie sogar von Array ableiten möchten) und intern mit den ursprünglichen Arrays verknüpft ist, um die Werte zu lesen. AFAIK Concat macht genau das.
In Ihrem Beispielcode könnten Sie jedoch .ToArray () weglassen, was es effizienter machen würde.
quelle
Es tut mir leid, einen alten Thread wiederzubeleben, aber wie wäre es damit:
Dann in Ihrem Code:
Bis Sie nennen
.ToArray()
,.ToList()
oder.ToDictionary(...)
ist der Speicher nicht zugeordnet sind , können Sie auf „Ihre Abfrage zu erstellen“ und entweder Aufruf einer dieser drei , um es auszuführen oder einfach gehen durch sie alle durch die Verwendungforeach (var i in z){...}
von der Klausel , die zu einem Zeitpunkt ein Element zurückgibtyield return t;
über...Die obige Funktion kann wie folgt in eine Erweiterung umgewandelt werden:
Im Code können Sie also Folgendes tun:
Der Rest ist der gleiche wie zuvor.
Eine weitere Verbesserung würde dies sich ändern
T[]
inIEnumerable<T>
(so dasparams T[][]
werden würdeparams IEnumerable<T>[]
) , um diese Funktionen zu machen akzeptieren mehr als nur Arrays.Hoffe das hilft.
quelle
Sie können es so machen, wie Sie es erwähnt haben, oder wenn Sie wirklich manuell darüber erfahren möchten, können Sie Ihre eigene Schleife rollen:
quelle
Ich habe eine elegante einzeilige Lösung mit LINQ- oder Lambda- Ausdruck gefunden, beide funktionieren gleich (LINQ wird beim Kompilieren des Programms in Lambda konvertiert). Die Lösung funktioniert für jeden Array-Typ und für eine beliebige Anzahl von Arrays.
Verwenden von LINQ:
Verwenden von Lambda:
Ich habe beides nach Belieben bereitgestellt. Performance weise @Sergey Shteyn des oder @ deepee1 Die Lösungen sind ein bisschen schneller, Lambda Ausdruck der langsamste ist. Die benötigte Zeit hängt vom Typ (den Typen) der Array-Elemente ab. Wenn jedoch nicht Millionen von Aufrufen vorliegen, gibt es keinen signifikanten Unterschied zwischen den Methoden.
quelle
Was Sie beachten müssen, ist, dass Sie bei Verwendung von LINQ eine verzögerte Ausführung verwenden. Die anderen hier beschriebenen Methoden funktionieren alle einwandfrei, werden jedoch sofort ausgeführt. Darüber hinaus ist die Concat () - Funktion wahrscheinlich so optimiert, wie Sie es nicht selbst tun können (Aufrufe interner APIs, Betriebssystemaufrufe usw.). Wie auch immer, wenn Sie nicht wirklich versuchen müssen, zu optimieren, befinden Sie sich derzeit auf dem Weg zur "Wurzel allen Übels";)
quelle
Versuche Folgendes:
quelle
Hier ist meine Antwort:
Diese Methode kann auf Initialisierungsebene verwendet werden, um beispielsweise eine statische Verkettung statischer Arrays zu definieren:
Es gibt jedoch zwei Einschränkungen, die Sie berücksichtigen müssen:
Concat
Methode erstellt einen Iterator über beide Arrays: Sie erstellt kein neues Array und ist somit hinsichtlich des verwendeten Speichers effizient. Die nachfolgende MethodeToArray
negiert jedoch diesen Vorteil, da tatsächlich ein neues Array erstellt wird und der Speicher für das Array belegt wird neues Array.Concat
wäre es für große Arrays eher ineffizient: Es sollte nur für mittelgroße Arrays verwendet werden.Wenn das Streben nach Leistung ein Muss ist, kann stattdessen die folgende Methode verwendet werden:
Oder (für Einzeiler-Fans):
Obwohl die letztere Methode viel eleganter ist, ist die erstere definitiv besser für die Leistung.
Weitere Informationen finden Sie in diesem Beitrag in meinem Blog.
quelle
Für int [] sieht das, was du getan hast, für mich gut aus. Astanders Antwort würde auch gut funktionieren für
List<int>
.quelle
Für kleinere Arrays <10000 Elemente:
quelle
Ich denke, die obige Lösung ist allgemeiner und leichter als die anderen, die ich hier gesehen habe. Es ist allgemeiner, weil es die Verkettung nicht nur für zwei Arrays einschränkt und leichter ist, weil es weder LINQ noch List verwendet.
Beachten Sie, dass die Lösung präzise ist und die hinzugefügte Allgemeinheit keinen signifikanten Laufzeitaufwand verursacht.
quelle
int [] x = new int [] {1, 2, 3}; int [] y = new int [] {4, 5};
int [] z = x.Union (y) .ToArray ();
quelle
Union
Dies ist keine sehr gute Möglichkeit, da implizitDistinct
alle Duplikate aus der verknüpften Sammlung aufgerufen und entfernt werden.Concat
ist viel besser, aber es ist bereits in der ursprünglichen Frage.quelle