2 people like it.

Reverse unicode string

Reverse unicode string, who may contains surrogate pairs

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
open System
open System.Globalization
open System.Collections

let seqOfEnumerator<'T> (e: IEnumerator) = seq {
    while e.MoveNext() do yield e.Current :?> 'T
}

let reverse (s: string) =
    s
    |> StringInfo.GetTextElementEnumerator
    |> seqOfEnumerator<string>
    |> Seq.rev
    |> String.concat ""

let display (s) =
  printfn "original: %s" s
  printfn "ok      : %s" (reverse s)
  printfn "naive   : %s" (s.ToCharArray() |> Array.rev |> System.String)

display "foo 𝌆 bar mañana mañana"
display "𠈓"
display "Les Mise\u0301rables"
namespace System
namespace System.Globalization
namespace System.Collections
val seqOfEnumerator : e:IEnumerator -> seq<'T>
val e : IEnumerator
type IEnumerator =
  member Current : obj
  member MoveNext : unit -> bool
  member Reset : unit -> unit
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

--------------------
type seq<'T> = Generic.IEnumerable<'T>
val reverse : s:string -> string
val s : string
Multiple items
val string : value:'T -> string

--------------------
type string = String
Multiple items
type StringInfo =
  new : unit -> StringInfo + 1 overload
  member Equals : value:obj -> bool
  member GetHashCode : unit -> int
  member LengthInTextElements : int
  member String : string with get, set
  member SubstringByTextElements : startingTextElement:int -> string + 1 overload
  static member GetNextTextElement : str:string -> string + 1 overload
  static member GetTextElementEnumerator : str:string -> TextElementEnumerator + 1 overload
  static member ParseCombiningCharacters : str:string -> int[]

--------------------
StringInfo() : StringInfo
StringInfo(value: string) : StringInfo
StringInfo.GetTextElementEnumerator(str: string) : TextElementEnumerator
StringInfo.GetTextElementEnumerator(str: string, index: int) : TextElementEnumerator
module Seq

from Microsoft.FSharp.Collections
val rev : source:seq<'T> -> seq<'T>
Multiple items
type String =
  new : value:char[] -> string + 8 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool + 3 overloads
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 3 overloads
  member EnumerateRunes : unit -> StringRuneEnumerator
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  ...

--------------------
String(value: char []) : String
String(value: nativeptr<char>) : String
String(value: nativeptr<sbyte>) : String
String(value: ReadOnlySpan<char>) : String
String(c: char, count: int) : String
String(value: char [], startIndex: int, length: int) : String
String(value: nativeptr<char>, startIndex: int, length: int) : String
String(value: nativeptr<sbyte>, startIndex: int, length: int) : String
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : String
val concat : sep:string -> strings:seq<string> -> string
val display : s:string -> unit
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...
val rev : array:'T [] -> 'T []
Raw view Test code New version

More information

Link:http://fssnip.net/7ZG
Posted:4 years ago
Author:Enrico Sada
Tags: string , string manipulation , unicode