Nehmen wir an, ich möchte einen String mit verschiedenen öffnenden und schließenden Klammern analysieren (Ich habe Klammern im Titel verwendet, weil ich glaube, dass es häufiger ist - die Frage ist trotzdem die gleiche), so dass ich alle höheren Ebenen getrennt bekomme eine Liste.
Gegeben:
%Vor%Ich möchte:
%Vor%Wie ich das tue, zähle ich die öffnenden und schließenden Klammern und füge die Liste hinzu, wenn ich meinen Zähler auf 0 setze. Allerdings habe ich einen hässlichen Imperativ-Code. Sie können annehmen, dass die ursprüngliche Zeichenfolge gut gebildet ist.
Meine Frage ist: Was wäre ein schöner funktionaler Ansatz für dieses Problem?
Anmerkungen: Ich habe überlegt, das for ... yield-Konstrukt zu verwenden, aber angesichts der Verwendung der Zähler kann ich keine einfache Bedingung bekommen (ich muss nur Bedingungen für die Aktualisierung der Zähler haben) und ich weiß nicht, wie ich könnte dieses Konstrukt in diesem Fall verwenden.
Schnelle Lösung mit Scala Parser-Kombinator-Bibliothek:
%Vor%Überprüfen Sie es in REPL:
%Vor%Angesichts Ihrer Anforderungen scheint die Klammer perfekt zu sein. Wie würden Sie das auf eine funktionale Art und Weise tun? Sie können den Status explizit weitergeben.
Also definieren wir zuerst unseren Zustand, der Ergebnisse in blocks
anhäuft oder die nächste block
verkettet und die Tiefe verfolgt:
Dann schreiben wir eine reine Funktion, die verarbeitet, die den nächsten Zustand zurückgibt. Hoffentlich können wir uns diese eine Funktion genau ansehen und sicherstellen, dass sie korrekt ist.
%Vor% Dann haben wir nur ein foldLeft
verwendet, um die Daten mit einem Anfangszustand zu verarbeiten:
Was zurückgibt:
%Vor%Sie haben eine hässliche imperative Lösung, also warum nicht eine gut aussehende? :)
Dies ist eine imperative Übersetzung von huynhjls Lösung, aber nur um zu zeigen, dass manchmal Imperativ prägnant und vielleicht einfacher zu folgen ist.
%Vor%Tags und Links scala functional-programming