F#, seq char -> Saiten
Eine kurze Frage, die möglicherweise eher ein rant (ich hoffe aber, erleuchtet zu werden, statt).
In F# ein string ist kompatibel mit Seq solche, die "abcd" |> Seq.Karte f funktionieren auf einer Schnur.
Dies ist eine geniale Einrichtung für die Arbeit mit strings, z.B. die ersten 5 Zeichen aus einem string:
"abcdef01234567" |> Seq.take 5
Oder entfernen von doppelten Zeichen:
"abcdeeeeeee" |> Seq.distinct
Das problem ist, dass wenn man einmal den char seq Ergebnis, wird es extrem umständlich zu konvertieren, das wieder in einen string wieder, Zeichenfolge.concat "" erfordert, dass die Mitglieder von strings, so dass ich am Ende tut viel:
"abcdef01234567"
|> Seq.take 5
|> Seq.map string
|> String.concat ""
So sehr, dass ich eine Funktion benutze ich in 90% meiner Projekte:
let toString : char seq -> string = Seq.map string >> String.concat ""
Ich glaube, das ist over the top, aber überall sehe ich eine Möglichkeit finden, ich bin erfüllt mit abscheulichen Dingen wie StringBuilder oder inlining eine lambda und die Nutzung neuer:
"abcdef01234567"
|> Seq.take 5
|> Seq.toArray
|> fun cs -> new string (cs) (* note you cannot just |> string *)
Meine (vielleicht verrückte) Erwartung, dass ich möchte, um zu sehen, in der Sprache ist, dass, wenn Seq verwendet wird, Zeichenfolge, geben Sie die Signatur aus dem resultierenden Ausdruck werden sollte, string -> Zeichenfolge. Bedeutung, was ist, was kommt. "abcd" |> Seq.3 = "abc".
Gibt es einen Grund, meine Erwartungen von high-level-string-manipulation verwechselt wird, in diesem Fall?
Hat jemand eine Empfehlung für die Annäherung an dieses in einer netten Art und Weise habe ich das Gefühl, ich muss etwas fehlen.
- Eine kleine Verbesserung, die Sie tun können
System.String("aa" |> Seq.take 1 |> Seq.toArray)
das ist etwas besser - mitSystem.String
bekommt eine implizitenew
kostenlos - nett, aber ich weiß wirklich nicht, wie das Aufbrechen der workflow und die Platzierung des letzten Ausdrucks in einer Funktion an der start |> fun-cs -> neu ... fühlt sich an wie das einzig mögliche Kompromiss (denn ich kann nicht lassen Sie es nehmen n = Seq.nehmen Sie n >> Seq.toArray >> Zeichenfolge >:( )
- Warum nicht einfach
"abcdef01234567".Substring(0, 5)
? Ich könnte mir vorstellen, dass die F# - String-Modul fehlt dietake
Funktion, gerade weil diese Instanz die Methode existiert in den Rahmen. - leider weiß ich nicht die Zusammensetzung ich möchte mit substring, oft erfordert das, was ich wahrnehmen werden unncess. geben Sie Signaturen und die Verwendung von Tupeln und Punkte, es fühlt sich einfach unsauber
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich war gerade die Erforschung dieser mich. Ich fand, dass System.String.Concat funktioniert ziemlich gut, z.B.
unter der Annahme, dass Sie geöffnet haben
System
.Funktionen in der
Seq
Modul nur mit Sequenzen, D. H., wenn Sie es nennen, mit einemstring
Sie nur "sehen", eineSeq<char>
und betreiben ihn entsprechend. Auch wenn Sie eine Besondere Prüfung, um zu sehen, wenn das argument einestring
und nahm einige spezielle Maßnahmen (z.B. eine optimierte version der Funktion nur für Streicher), Sie würden immer noch zurückgeben, da eineSeq<char>
zu beschwichtigen, die F# type system -, in welchem Fall würden Sie brauchen, um den Rückgabewert überprüfen überall zu sehen war, wenn es tatsächlich einestring
.Die gute Nachricht ist, dass F# hat eine eingebaute Verknüpfungen für einige der code Sie schreiben. Zum Beispiel:
kann verkürzt werden zu:
Einige andere, werden Sie noch verwenden Sie
Seq
obwohl, oder schreiben Sie Ihre eigenen optimierten Umsetzung zu arbeiten mit Zeichenfolgen.Hier ist eine Funktion, um das deutliche Zeichen in einem string:
F# hat eine String-Modul die enthält einige der
Seq
Modul-Funktionalität speziell für strings.F# gewonnen hat, die Fähigkeit zur Nutzung von Konstruktoren als Funktionen, da diese Frage wurde bereits vor 5 Jahren. Ich würde String(Char[]) zum konvertieren von Zeichen in einen string. Sie können konvertieren Sie zu und von einer F# - Sequenz oder ein F# - Liste, aber ich würde wahrscheinlich nur die F# - array-Modul mit String.ToCharArray Methode zu.
Wenn Sie wirklich wollten mit einem
char seq
dann Sie können über die Pipeline eine Zeichenfolge etwa so: