有没有办法使用一行代码以独特的方式获取数组并修改每个单独的元素?
Is there a way to take an array and modify each individual element in a unique way using a single line of code?
我正在尝试修改 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 版之前,有什么方法可以做这样的事情吗?
我也对其他想法持开放态度,但同样,目标是尽可能短的单行代码,以及使用不同参数修改 2 个元素的能力。
请注意:无法升级到 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
and 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
方法,如以下 2 个示例所示:
[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
我正在尝试修改 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 版之前,有什么方法可以做这样的事情吗?
我也对其他想法持开放态度,但同样,目标是尽可能短的单行代码,以及使用不同参数修改 2 个元素的能力。
请注意:无法升级到 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
and 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
方法,如以下 2 个示例所示:
[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