Schreiben des F # rekursiven Ordner-Besuchers in C # - seq vs IEnumerable

7

Ich benutze diesen rekursiven "Besucher" oft in F #

%Vor%

Vor kurzem habe ich begonnen, einige F # -Funktionalitäten in C # zu implementieren, und ich versuche, dies als IEnumerable zu reproduzieren, aber ich habe Schwierigkeiten, weiter zu kommen:

%Vor%

Was ich nicht verstehe, ist, warum ich eine doppelte foreach in der C # Version für die Rekursion machen muss, aber nicht in F # ... Führt die seq {} implizit eine 'concat' aus?

    
Benjol 21.11.2008, 11:26
quelle

4 Antworten

12

yield! führt eine 'flatten' -Operation durch, so dass die Sequenz in die äußere Sequenz integriert wird, wobei implizit ein foreach für jedes Element der Sequenz und yield für jedes Element ausgeführt wird.

    
Sunlight 21.11.2008, 12:27
quelle
3

Es gibt keine einfache Möglichkeit, dies zu tun. Sie könnten dies umgehen, indem Sie einen C # -Typ definieren, der entweder einen Wert oder eine Folge von Werten speichern kann - unter Verwendung der F # -Notation wäre dies:

%Vor%

(übersetze das in C # wie du willst: -))

Nun könnten Sie etwas schreiben wie:

%Vor%

Um es zu verwenden, müssten Sie eine Funktion schreiben, die EnumerationResult flacht, was eine Erweiterungsmethode in C # mit der folgenden Signatur sein könnte:

%Vor%

Nun, das ist ein Teil, wo es schwierig wird - wenn Sie dies geradlinig implementieren würden, würde es immer noch "forach" enthalten, um über die verschachtelten "Seq" -Ergebnisse zu iterieren. Ich glaube jedoch, dass Sie eine optimierte Version schreiben könnten, die keine quadratische Komplexität hätte.

Ok ... Ich schätze, das ist ein Thema für einen Blogbeitrag, anstatt etwas, das hier vollständig beschrieben werden könnte :-), aber hoffentlich zeigt es eine Idee, der Sie folgen können!

[EDIT: Aber natürlich können Sie auch eine naive Implementierung von "Flatten" verwenden, die "SelectMany" verwenden würde, nur um die Syntax Ihres C # Iterator-Codes schöner zu machen]

    
Tomas Petricek 21.11.2008 16:24
quelle
2

Im speziellen Fall des Abrufens aller Dateien in einem bestimmten Verzeichnis diese Überladung von Directory.GetFiles funktioniert am besten:

%Vor%


Im allgemeinen Fall des Durchquerens eines Baumes von aufzählbaren Objekten ist eine verschachtelte foreach-Schleife oder ein Äquivalent erforderlich (siehe auch: Alles über Iteratoren ).

Bearbeiten: Es wurde ein Beispiel für eine Funktion hinzugefügt, um einen beliebigen Baum in eine Aufzählung einzufügen:

%Vor%

Dies kann verwendet werden, um alle verschachtelten Dateien wie zuvor auszuwählen:

%Vor%     
Emperor XLII 29.11.2008 03:46
quelle
2

In C # verwende ich den folgenden Code für diese Art von Funktion:

%Vor%

Dies adressiert E / A-Fehler (was leider unvermeidlich passiert) und vermeidet Endlosschleifen aufgrund symbolischer Links (insbesondere werden Sie bei der Suche nach einigen Verzeichnissen in Windows 7 darauf stoßen).

    
Eamon Nerbonne 26.04.2010 20:56
quelle

Tags und Links