我正试图修改Ruby 2.4中的一个变量字符串,该字符串包含一个数字和一个测量单位。我的目标是取以下字符串,将数字部分四舍五入,并将单位部分大写:
my_string = "123.456789 dollars"
据我所知,有各种各样的方法可以用多行代码来完成此操作,但我使用的是一个独特的接口,并且在一个唯一的环境中,目标是使用尽可能短的单行代码来编写此操作。我知道我可以做这样的事情:
my_array =my_string.split; my_array[0].to_f.round(2).to_s + " " + my_array[1].capitalize
但我的目标是去掉分号,减少字符的使用,避免两次调用数组。
我的想法是做一些类似于的事情
my_string.split.*do_this*(self.to_f.round(2), self.capitalize).join(" ")
在2.5版本之前,有什么方法可以做到这一点吗?
我也对其他想法持开放态度,但同样,目标是尽可能短的一行代码,并能够在每行代码上使用不同的参数修改这两个元素。
请注意:升级到Ruby的新版本不是一个选项。2.4是目前硬编码到我们正在使用的软件包中的版本。
如果只有两个元素,可以使用then
和字符串插值:
my_string.split.then { |f, s| "#{f.to_f.round(2)} #{s.capitalize}" }
或者可能是其中之一:
my_string.split.then { |f, s| sprintf("%.2f #{s.capitalize}", f) }
my_string.split.then { |f, s| sprintf('%.2f %s', f, s.capitalize) }
my_string.split.then { |f, s| "%.2f #{s.capitalize}" % f }
或者,如果可能有两个以上的元素,可以将map
和with_index
:组合起来
my_string.split.map.with_index { |e, i| i == 0 ? e.to_f.round(2) : e.capitalize }.join(' ')
我发现在Ruby 2.4中,我们可以至少以几种不同的方式使用instance_eval
方法,例如:
my_string.split.instance_eval { |f, s| "#{f.to_f.round(2)} #{s.capitalize}" }
或
my_string.split.instance_eval { |a| "#{a[0].to_f.round(2)} #{a[1].capitalize}" }
或
my_string.split.instance_eval { |f, s| [f.to_f.round(2), s.capitalize]}.join(" ")
我们也可以使用tap
方法,它只需要更多的几个字符:
my_string.split.tap { |a| a[0..-1] = [a[0].to_f.round(2), a[1].capitalize]}.join(" ")
或者我们甚至可以通过创建嵌套数组来使用map
方法,如以下两个示例所示:
[my_string.split].map{|a| "#{a[0].to_f.round(2)} #{a[1].capitalize}"}.join
和
[my_string.split].map{|a| [a[0].to_f.round(2)," ",a[1].capitalize]}.join
作为额外的奖励,我们甚至可以做一些不需要使用块的事情:
(a, b = my_string.split).replace([a.to_f.round(2)," ",b.capitalize ]).join