39
things = "one thing, two things, three things, four things"

鉴于此输入,我如何用逗号分割字符串,然后将其周围的空格修剪到位?导致:

things = ["one thing", "two things", "three things", "four things"]

目前我有这个:

things = things.to_s.tr("\n\t", "").strip.split(/,/)

这完成了我想要它做的大部分工作,除了在逗号拆分时删除前导/尾随空格。实现这一目标的最佳方法是什么?我想将其作为此表达式的一部分,而不是将上述结果分配给单独的数组并对其进行迭代。

4

5 回答 5

91
s = "one thing, two things, three things, four things"
s.split(",").map(&:strip)
# => ["one thing", "two things", "three things", "four things"]

在我的Ubuntu 13.04操作系统中,使用Ruby 2.0.0p0

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
  b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} }
  b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} }
end

Rehearsal -------------------------------------------------
strip/split:    6.260000   0.000000   6.260000 (  6.276583)
regex:          7.310000   0.000000   7.310000 (  7.320001)
--------------------------------------- total: 13.570000sec

                    user     system      total        real
strip/split:    6.350000   0.000000   6.350000 (  6.363127)
regex:          7.290000   0.000000   7.290000 (  7.302163)
于 2013-07-14T16:40:25.900 回答
8

使用正则表达式#split

"one thing, two things, three things, four things".split /\s*,\s*/
# => ["one thing", "two things", "three things", "four things"]
于 2013-07-14T16:40:32.147 回答
5

不要打死马,但是您可以通过进行两项更改来加快速度,这些更改现在已成为我的第二天性。第一个是使用map!而不是map避免创建拆分数组的副本,第二个是避免使用符号来处理语法(例如&:split,它添加了一个额外的操作,可以通过更详细的语法来避免)。

基准如下:

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
    b.report("strip/split (map/to_proc): ") { 1_000_000.times { result = s.split(",").map(&:strip) } }
    b.report("strip/split (map): ") { 1_000_000.times { result = s.split(",").map { |e| e.strip } } }
    b.report("strip/split (map!/to_proc): ") { 1_000_000.times { result = s.split(",").map!(&:strip) } }
    b.report("strip/split (map!): ") { 1_000_000.times { result = s.split(",").map! { |e| e.strip } } }
    b.report("regex: ") { 1_000_000.times { result = s.split(/\s*,\s*/) } }
end

结果:

                                   user     system      total        real
strip/split (map/to_proc):     5.230000   0.010000   5.240000 (  5.283079)
strip/split (map):             4.660000   0.010000   4.670000 (  4.716920)
strip/split (map!/to_proc):    4.440000   0.020000   4.460000 (  4.492943)
strip/split (map!):            4.320000   0.010000   4.330000 (  4.365386)
regex:                         7.190000   0.060000   7.250000 (  7.322932)

请记住阅读相对于彼此的数字,而不是相对于其他答案中提供的基准。

于 2013-12-23T00:26:32.807 回答
2

这并不是对原始问题的回答,但我想分享基准代码,让人们自己检查两个提议的解决方案:

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
  b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} }
  b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} }
end

在我的系统(OS X 10.8 上的 Ruby 2.0.0p247)上产生以下输出:

Rehearsal -------------------------------------------------
strip/split:    2.140000   0.000000   2.140000 (  2.143905)
regex:          3.570000   0.010000   3.580000 (  3.572911)
---------------------------------------- total: 5.720000sec

                    user     system      total        real
strip/split:    2.150000   0.000000   2.150000 (  2.146948)
regex:          3.580000   0.010000   3.590000 (  3.590646)

当然,这些结果可能会因 ruby​​ 版本、硬件和操作系统而异。

于 2013-07-14T18:09:17.817 回答
2

如果我没错的话

things.split(", ")

将是最简单的解决方案。但是,它仅在只有一个空格字符时才有效。(注意逗号后面的空格)

于 2015-05-19T18:09:06.657 回答