F# 如何使用sprintf格式化以逗号作为千位分隔符的整数

F# 如何使用sprintf格式化以逗号作为千位分隔符的整数,f#,inline,F#,Inline,如何使用sprintf格式化整数以将逗号显示为数千个分隔符 我知道如何使用String.Format,但我找不到使用sprintf的方法 编辑:根据下面Fyodor Soikin的评论,我尝试了以下代码: printf "%a" (fun writer (value:int) -> writer.Write("{0:#,#}", value)) 10042 let s = sprintf "%a" (fun writer (value:int) -> writer.Write("{0

如何使用sprintf格式化整数以将逗号显示为数千个分隔符

我知道如何使用String.Format,但我找不到使用sprintf的方法

编辑:根据下面Fyodor Soikin的评论,我尝试了以下代码:

printf "%a" (fun writer (value:int) -> writer.Write("{0:#,#}", value)) 10042
let s = sprintf "%a" (fun writer (value:int) -> writer.Write("{0:#,#}", value)) 10042
printf调用可以工作(但会写入标准输出,而我希望获得一个字符串,可以分配给WPF控件的Text或Content属性)

sprintf调用失败,错误为FS0039:未定义字段、构造函数或成员“Write”


如果我可以修复这个错误,那么这可能是最直接的解决方案,当与部分应用程序结合使用时,它将与内置版本一样简洁。

这是可行的,但应该有一种更简单的方法

let thousands(x:int64) = 
    System.String.Format("{0:#,0}", x)

let s = sprintf "%s" (thousands(0L))
printfn "%s" s

let s = sprintf "%s" (thousands(1L))
printfn "%s" s

let s = sprintf "%s" (thousands(1000L))
printfn "%s" s

let s = sprintf "%s" (thousands(1000000L))
printfn "%s" s

0
1
1,000
1,000,000
稍好一点的版本

let printNumber (x : int) : string =
    System.String.Format("{0:N0}",x)

由于无法使用Printf模块执行此操作,因此我的操作如下:

/// Calls ToString on the given object, passing in a format-string value.
let inline stringf format (x : ^a) = 
    (^a : (member ToString : string -> string) (x, format))
someNumber |> stringf "N0"
然后这样称呼它:

/// Calls ToString on the given object, passing in a format-string value.
let inline stringf format (x : ^a) = 
    (^a : (member ToString : string -> string) (x, format))
someNumber |> stringf "N0"
以下是一个函数:

let thousands n =
    let v = (if n < 0 then -n else n).ToString()
    let r = v.Length % 3 
    let s = if r = 0 then 3 else r
    [   yield v.[0.. s - 1]
        for i in 0..(v.Length - s)/ 3 - 1 do
            yield v.[i * 3 + s .. i * 3 + s + 2]
    ]
    |> String.concat ","
    |> fun s -> if n < 0 then "-" + s else s
n=
设v=(如果n<0,则-n else n).ToString()
设r=v.长度%3
设s=如果r=0,则为3,否则为r
[收益率v[0..s-1]
对于0..(v.Length-s)/3-1DO中的i
收益率v.[i*3+s..i*3+s+2]
]
|>String.concat“,”
|>乐趣s->如果n<0,则“-”+s否则s
下面是另一个包含一些帮助程序扩展成员的帮助程序:

type System.String with
    member this.Substring2(from, n) = 
        if   n    <= 0           then ""
        elif from >= this.Length then ""
        elif from <  0           then this.Substring2(0, n + from)
        else this.Substring(from, min n (this.Length - from))
    member this.Left             n  = if n < 0 
                                    then this.Substring2(0, this.Length + n)
                                    else this.Substring2(0, n              )
    member this.Right            n  = this.Substring2(max 0 (this.Length - n), this.Length)

let thousands (n:int) =
    let rec thousands acc = 
        function
        | "" -> acc
        | x  -> thousands (x.Right 3 + if acc = "" then "" else "," + acc) (x.Left -3)
    if n < 0 then -n else n
    |> string
    |> thousands ""
    |> fun s -> if n < 0 then "-" + s else s
键入System.String和
此成员。子字符串2(从,n)=
如果n=此.Length,则“”
elif from<0,则此子字符串2(0,n+from)
否则此.Substring(from,min n(this.Length-from))
此成员。如果n<0,则左n=此成员
然后这个.Substring2(0,这个.Length+n)
否则,该子字符串2(0,n)
成员this.Right n=this.Substring2(最大0(this.Length-n),this.Length)
千分之一(n:int)=
让rec数千acc=
功能
|“->acc
|x->千(x.右3+如果acc=”“,则“else”、“+acc)(x.左-3)
如果n<0,则-n否则n
|>串
|>千“
|>乐趣s->如果n<0,则“-”+s否则s

对不起,这是作弊。我正在寻找一个不依赖String.Format的答案。换句话说,只使用sprintf,而不使用.NETFramework库。感谢您的尝试。首先,使用F#格式说明符无法做到这一点。其次,很抱歉让您失望,但是F#format函数确实使用了下面的.NET FW库,特别是
TextWriter
。通过使用格式说明符
%t
%a
,您可以直接连接到底层的
TextWriter
。这很有趣,但我想我不能授予“X奖”,因为使用ToString并不比使用String.format好。我能够在下面的示例中使用您的解决方案,并以面向对象的方式直接调用ToString。但我还是个F#初学者,所以我对你的^a语法感到非常困惑。我熟悉“a”(通用值),但什么是^a?谢谢设x=42345 |>stringf“N0”//>val x:string=“42345”let x'=44325L.ToString(“N0”)/>val x:string=“44325”带有
^a
内联
函数基本上可以被认为是duck类型。在这种情况下,
stringf
函数将处理任何具有
ToString
方法的对象,该方法将字符串作为输入并返回字符串。如果您尝试将其用于一个没有ToString重载的对象,您将得到一个编译器错误。换句话说,
stringf
是调用
ToString(string)
的函数方式,就像内置的
string
函数是调用
ToString()的函数方式一样。至于“不比使用String.Format更好”是什么让您认为有更好的方法呢?从技术上讲,它是一个
成员约束调用表达式
。《JoelMueller re》中描述了这一点:“什么让你认为有更好的方法”:就像所有的科学实验一样,在你尝试之前,你永远不会知道。很明显,sprintf没有内置的方法来实现这一点,但也许有一种方法可以使用扩展方法来重载它。我非常感谢你的帮助。谢谢。感兴趣的:感兴趣的:关于sprintf的使用: