在Ruby

时间:2015-11-06 09:21:12

标签: ruby string format string-formatting

是否有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?

# convert numbers to strings of fixed length 3 
[1, 12, 123, 1234].map { |e| ??? }
=> ["001", "012", "123", "234"]

我找到了解决方案,但也许有更聪明的方法。

format('%03d', e)[-3..-1]

5 个答案:

答案 0 :(得分:7)

如何使用% 1000而不是进行字符串操作来获取最后三位数?

[1, 12, 123, 1234].map { |e| format('%03d', e % 1000) }

更新

正如the Tin Man在评论中所建议的那样,原始版本在可读性方面更好,并且只比这一版慢了1.05倍,因此在大多数情况下使用它可能是有意义的。

答案 1 :(得分:2)

基准:

require 'fruity'

VALUES = (1..9999).to_a.shuffle.take(100)

5.times do
  compare do
    original { VALUES.map { |e| format('%03d', e)[-3..-1] } }
    w0lf     { VALUES.map { |e| format('%03d', e % 1000) } }
    owade    { VALUES.map { |e| e.to_s.rjust(3,'0')[-3..-1]} }
    sdayal   { VALUES.map { |e| ("%03d" % e)[/...$/] } }
  end
  puts
end
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is faster than original by 39.99999999999999% ± 10.0%
# >> original is faster than sdayal by 2x ± 0.1
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 0.1
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 1.0
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 1.0
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 0.1
# >> 

我使用了五次迭代,因为结果没有稳定。可能是因为我的机器上正在运行备份,影响了处理。外卖是一致的,使用正则表达式来获取最后三个值是不可取的。虽然各种方法之间的差异对于单个阵列可能并不重要,但重复该过程数千次并且可以累加起来。

答案 2 :(得分:0)

[1, 12, 123, 1234].map { |e| ("%03d" % e)[/...$/] }

答案 3 :(得分:0)

您可以将modula分区%String#% - 方法结合使用。 (你不需要format - 命令):

[1, 12, 123, 1234].map { |e| "%03d" % (e % 1000)}

用一些标记来解释不同的%

[1, 12, 123, 1234].map { |e| "%03d" % (e % 1000)}
#                            (1)   (2)   (3)
  • (1):格式规范,带前导零的3个数字。
  • (2):String#% - 方法
  • (3):整数的Modula划分

w0lf's answer的评论中,您提及: 格式字符串和除数之间仍存在这种依赖/重复。

您可以定义变量中的位数,并在格式字符串和除数中使用它:

digits = 3
[1, 12, 123, 1234].map { |e| "%0*d" % [digits,e % 10**digits]}

答案 4 :(得分:0)

您可以使用String#rjust。它右键填充(右对齐)一个字符串,使其成为给定的长度,使用给定的填充字符。

[1, 12, 123, 1234].map { |e| e.to_s.rjust(3,'0')[-3..-1]}