2010-08-03 23 views
6

Sadece F # öğreniyorum ve C# uzantısı yöntemlerini bir kitaplığa F # dönüştürüyorum. Şu anda altına C# uygulamasına dayalı ConvertFirstLetterToUppercase adlı bir işlev uygulama üzerinde çalışıyorum:F # string manipülasyonunun optimizasyonu

public static string ConvertFirstLetterToUppercase(this string value) { 
    if (string.IsNullOrEmpty(value)) return value; 
    if (value.Length == 1) return value.ToUpper(); 
    return value.Substring(0, 1).ToUpper() + value.Substring(1); 
} 

F # uygulaması

[<System.Runtime.CompilerServices.ExtensionAttribute>] 
module public StringHelper 
    open System 
    open System.Collections.Generic 
    open System.Linq 

    let ConvertHelper (x : char[]) = 
     match x with 
      | [| |] | null -> "" 
      | [| head; |] -> Char.ToUpper(head).ToString() 
      | [| head; _ |] -> Char.ToUpper(head).ToString() + string(x.Skip(1).ToArray()) 

    [<System.Runtime.CompilerServices.ExtensionAttribute>] 
    let ConvertFirstLetterToUppercase (_this : string) = 
     match _this with 
     | "" | null -> _this 
     | _ -> ConvertHelper (_this.ToCharArray()) 

Birisi bana daha doğal F # kullanan bir daha özlü uygulanmasını gösterebilir sözdizimi?

+0

Yanıtlar için herkese teşekkürler, bazı yeni operatörler öğrendim ve desen eşleştirmeyi nasıl kullanacağımı öğrendim. :-) Bir sonraki adımı tahmin ediyorum? Performans testi? lol –

cevap

5

şey?

[<System.Runtime.CompilerServices.ExtensionAttribute>] 
module public StringHelper = 
[<System.Runtime.CompilerServices.ExtensionAttribute>] 
let ConvertFirstLetterToUppercase (t : string) = 
    match t.ToCharArray() with 
    | null -> t 
    | [||] -> t 
    | x -> x.[0] <- Char.ToUpper(x.[0]); System.String(x) 
+2

Bunu beğendim, sadece bir not, satır sayısını azaltmak için boş veya boş dizi denetimlerini aşağıdakiyle birleştirebilirsiniz: | null | [||] -> bu –

4

aşağıdaki

[<System.Runtime.CompilerServices.ExtensionAttribute>] 
module StringExtensions = 
    let ConvertFirstLetterToUpperCase (data:string) = 
     match Seq.tryFind (fun _ -> true) data with 
     | None -> data 
     | Some(c) -> System.Char.ToUpper(c).ToString() + data.Substring(1) 

tryFind işlev lambda true döndürdüğü ilk elemanı döndürür inceleyin. Her zaman doğru döndüğü için ilk elemanı veya None'u döndürür. En az bir öğe olduğunda oluşturduktan sonra size datanull değil biliyorum ve dolayısıyla alt dize arayabilir

+0

Çözümü beğendim! Sonuçların dizilerle çalışacağını umuyordum, bu yüzden sonucu gerçekten yaratan ifadede kalıp eşleştirmesi yapabildim, ama uygulamaların bir parçası değil. : -/ –

17
open System 

type System.String with 
    member this.ConvertFirstLetterToUpperCase() = 
     match this with 
     | null -> null 
     | "" -> "" 
     | s -> s.[0..0].ToUpper() + s.[1..] 

Kullanımı: Böyle

> "juliet".ConvertFirstLetterToUpperCase();; 
val it : string = "Juliet" 
+1

Şimdi, eğer alt dizelerden biraz daha verimli bir şey istiyorsanız, şunu deneyin: chars = s.ToCharArray(); karakter. [0] <- Char.ToUpper (chars. [0]); Yeni String (karakter) ' – Juliet

+0

+1, [n..n] kullanımını seviyorum. İyi durumda bir bofer uygulamasında görmedim. – JaredPar

+0

Dizi sürümü gerçekten daha hızlı mı? Altyazı sürümü, neredeyse tüm dizenin bir kopyasını (s. [1 ..]) yapar ve daha sonra bu karakter ilk karaktere eklendiğinde başka bir dize oluşturulur. Dizi sürümü dizeyi bir diziye kopyalar, daha sonra dizi bir dizeye kopyalanır. Her iki şekilde de 2 kopya işlemi gibi görünüyor - ya da dizi dönüştürme, kopyalama işleminden daha hızlı mı? –

2

.NET kitaplık işlevlerini bir .NET dilinden kullanmanın bir sorunu yoktur. Belki C# uzantısı yönteminizin doğrudan çevirisi, özellikle böyle basit bir işlev için en uygunudur. Juliet gibi dilbilgisi sözdizimini kullanmak cazip olsa da, sadece iyi olduğu için.

open System 
open System.Runtime.CompilerServices 

[<Extension>] 
module public StringHelper = 

    [<Extension>] 
    let ConvertFirstLetterToUpperCase(this:string) = 
     if String.IsNullOrEmpty this then this 
     elif this.Length = 1 then this.ToUpper() 
     else this.[0..0].ToUpper() + this.[1..] 
+0

Gerçekten, daha az ayrıntılı dil stili nedeniyle Framework API'sinde içsel dil özelliklerinin kullanımını tercih ediyorum. –

+0

Bu çok idiomatik görünmese bile, bana temiz bir çözüm gibi görünüyor. – Daniel