简体   繁体   English

有没有更简洁的方法来重写 F# function?

[英]Is there a more concise way to rewrite that F# function?

Here is a function that converts a number to a string with the requested precision and a leading sign:这是一个 function 将数字转换为具有所需精度和前导符号的字符串:

let formatValueSign (precision: decimal) (value: decimal) =
    let precisionString =
        match precision with
        | 0.1m      -> "{0:+#.0;-#.0; 0.0}"
        | 0.01m     -> "{0:+#.00;-#.00; 0.00}"
        | 0.001m    -> "{0:+#.000;-#.000; 0.000}"
        | 0.0001m   -> "{0:+#.0000;-#.0000; 0.0000}"
        | 0.00001m  -> "{0:+#.00000;-#.00000; 0.00000}"
        | 0.000001m -> "{0:+#.000000;-#.000000; 0.000000}"
        | _         -> "{0:+#0;-#0;0}"

    String.Format(precisionString, value)

The expected output has the sign in front of the number and the precision is represented by a decimal number, but it can also be passed as i where the precision is pown 0.1mi if it's more convenient.预期的 output 在数字前面有符号,精度用十进制数表示,但如果更方便,也可以作为i传递,精度为0.1mi

Is there a way to make this more concise?有没有办法让它更简洁?

If I understand what you want correctly, I think something like this does essentially the same thing:如果我正确理解你想要什么,我认为这样的事情本质上是一样的:

(Decimal.Round(value / precision) * precision).ToString()

And it also handles precision > 1, such as:它还处理精度> 1,例如:

formatValueSign 100m -12345.6789m -> "-12300"

You can tweak the ToString() part to generate the leading + sign if you want.如果需要,您可以调整ToString()部分以生成前导+符号。 Personally, I would break this into two functions, though: One to generate a decimal with the correct precision, and a separate one that formats it to your liking.不过,就个人而言,我会将其分解为两个函数:一个是生成具有正确精度的小数,另一个是根据您的喜好对其进行格式化。

Last thought: I would probably define the precision as an integer exponent (eg -2 instead of 0.01m ), because the current signature accepts precisions that aren't powers of 10. Better to make invalid values unrepresentable IMHO.最后的想法:我可能会将精度定义为 integer 指数(例如-2而不是0.01m ),因为当前签名接受不是 10 的幂的精度。最好使无效值无法表示恕我直言。

You could calculate the number of zeros in the format string using log10 and then generate the format string dynamically.您可以使用log10计算格式字符串中零的数量,然后动态生成格式字符串。 The following does not correctly handle corner cases, but it works for the cases in the middle of your range:以下内容不能正确处理极端情况,但适用于范围中间的情况:

let formatValueSign (precision: decimal) (value: decimal) =
  let places = int (log10 (float (1.0m/precision)))
  let zeros = String.replicate places "0"
  let precisionString = sprintf "{0:+#.%s;-#.%s; 0.%s}" zeros zeros zeros
  String.Format(precisionString, value)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM