"Turning" ein IEnumerableIEnumerableT 90 Grad

8

Was ich suche, ist eine grundlegende Operation (die ich sicher einen Namen habe, von dem ich nichts achte). Ich habe eine Matrix wie:

{1,2,3}

{A, N, F}

{7,8,9}

was ich gerne zu

mutieren würde

{1, A, 7}

{2, N, 8}

{3, F, 9}

(Die obigen sind nur Bezeichner für Objekte, die keine realen Werte sind. Die tatsächlichen Objekte sind vom gleichen Typ und ungeordnet)

Ich würde eine deklarative Lösung bevorzugen, aber Geschwindigkeit ist ein Faktor. Ich werde ziemlich viele Tabellen drehen müssen (100k Zellen pro Minute) und eine langsame Version wäre auf dem kritischen Pfad.

Aber ich bin immer noch mehr an einer lesbaren Lösung interessiert. Ich suche nach alternativen Lösungen für die folgenden. (Mit Alternative meine ich nicht Variationen, sondern einen anderen Ansatz)

%Vor%

Unter zwei fast gleich gut lesbaren Lösungen würde ich mich für das schnellere entscheiden, aber die Lesbarkeit geht vor Geschwindigkeit

BEARBEITEN Es wird immer eine quadratische Matrix sein

    
Rune FS 18.02.2011, 09:31
quelle

6 Antworten

10

Ich bin ein wenig unzufrieden mit dieser Implementierung. Es hat lokale Auswirkungen auf den Iterator, sieht aber für mich logisch sauber aus. Dies setzt voraus, dass jede Sequenz die gleiche Länge hat, aber für alle funktionieren sollte. Sie können sich dies als Zip() Methode mit variabler Länge vorstellen. Es sollte besser funktionieren als die anderen verknüpften LINQ-Lösungen, die in den anderen Antworten gefunden werden, da es nur die minimalen Operationen verwendet, die zum Arbeiten benötigt werden. Wahrscheinlich sogar besser ohne die Verwendung von LINQ. Könnte sogar als optimal angesehen werden.

%Vor%     
Jeff Mercado 18.02.2011, 09:58
quelle
4

Sehen Sie sich diese Erweiterungsmethode an. Linq transponieren . Ich bin mir nicht sicher über die Leistung, aber der Code sieht elegant aus.

    
Yury Tarabanko 18.02.2011 09:41
quelle
1

Ihre Frage scheint zu implizieren, dass Sie die ursprüngliche Matrix ändern möchten.

Wenn das der Fall ist, und wenn Sie die Matrix als IList<IList<T>> matrix speichern können, funktioniert das nur im Fall einer quadratischen Matrix.

%Vor%     
Ken Wayne VanderLinde 18.02.2011 09:47
quelle
0

Nun, was Sie hier suchen, ist eine Transformation T[][] -> T[][] . Es gibt viele IEnumerabe<IEnumerable<T>>.Transpose() -Lösungen in der Nähe, aber sie alle laufen auf Looping-Enumerables mit temporären Lookups / Keys und sie lassen viel zu wünschen übrig, wenn es um Leistung bei großem Volumen geht. Ihr Beispiel funktioniert tatsächlich schneller (obwohl Sie auch die zweite foreach verlieren könnten).

Zuerst fragen "brauche ich überhaupt LINQ". Sie haben nicht beschrieben, was der Zweck der transponierten Matrix sein wird und wenn die Geschwindigkeit tatsächlich Ihre Sorge ist, könnten Sie gut daran tun, einfach weg von der LINQ / foreach zu bleiben und es auf die altmodische Art und Weise (für innen) zu tun.

    
mmix 18.02.2011 10:03
quelle
0

Hier ist meins, wenn jemand interessiert ist. Es funktioniert in der gleichen Art wie Jeff, scheint aber etwas schneller zu sein (vorausgesetzt, dass ToArrays () notwendig sind). Es gibt keine sichtbaren Schleifen oder Provisorien und es ist viel kompakter:

%Vor%

Wenn Sie es auch brauchen, um leere Listen zu behandeln, dann wird dies:

%Vor%

Ich bemerkte, dass der Fragesteller schrieb, dass die Matrix immer quadratisch sein würde. Diese Implementierung (und Jeffs) wird eine ganze Reihe nach der anderen auswerten, aber wenn wir wissen, dass die Matrix quadratisch ist, können wir die Zip-Funktion in geeigneterer Weise neu schreiben:

%Vor%

Auf diese Weise wird jedes Element erst ausgewertet, wenn es zurückgegeben wird.

    
YellPika 07.07.2012 21:03
quelle

Tags und Links