Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there more simple or beautiful way to reverse a string?

Tags:

string

f#

Now I am using such a method:

let x_rev = new string(x.Reverse().ToArray())
like image 319
AndrewShmig Avatar asked Dec 29 '10 17:12

AndrewShmig


1 Answers

Here's some code based on Timwi's comment on Nate's answer. There are single logical letters (as displayed on screen) that are made up of more than one actual character. Reversing the order of the characters turns these letters into gibberish.

Timwi helpfully points out that the framework provides a TextElementEnumerator that works in terms of logical text elements rather than characters, and handles these multi-character letters correctly. I hadn't heard of this class before, so I wrote some code that uses a TextElementEnumerator to reverse a string correctly, and compare the results to a naive string reversal.

open System
open System.Globalization

// five characters that render as three letters: "𐀀àÆ"
let myString = "\uD800\uDC00\u0061\u0300\u00C6"

// naive reversal scrambles the string: "Æ̀a��"
// (note that while this produces the wrong results, 
//  it probably is faster on large strings than using
//  LINQ extension methods, which are also wrong)
let naive = String(myString.ToCharArray() |> Array.rev)

// use a TextElementEnumerator to create a seq<string> 
// that handles multi-character text elements properly
let elements = 
    seq {
        let tee = StringInfo.GetTextElementEnumerator(myString)
        while tee.MoveNext() do 
            yield tee.GetTextElement() 
    }

// properly reversed: "Æà𐀀"
let reversed = elements |> Array.ofSeq |> Array.rev |> String.concat ""
like image 88
Joel Mueller Avatar answered Nov 18 '22 15:11

Joel Mueller