Подтвердить что ты не робот

Рубин: Сплит, а затем удалить ведущие/конечные пробелы на месте?

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(/,/)

Это делает большую часть того, что я хочу сделать, за исключением удаления ведущего/конечного пробела, когда он разбивается на запятую. Какой лучший способ достичь этого? Я хотел бы сделать это как часть этого выражения, вместо того, чтобы присваивать вышеупомянутый результат отдельному массиву и повторять его.

4b9b3361

Ответ 1

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)

Ответ 2

Используйте регулярное выражение для #split:

"one thing, two things, three things, four things".split /\s*,\s*/
# => ["one thing", "two things", "three things", "four things"]

Ответ 3

Мне нравятся тесты... Но позвольте мне взглянуть на это, если вы не выполняете эту операцию внутри миллиона циклов в вашем коде, разницы в скорости являются спорными.

Следовательно, лучшее решение, вероятно, самое лучшее. Возможно, этот из Арупа Ракшита:

s = "one thing, two things, three things, four things"
s.split(",").map!(&:strip)

Ответ 4

Не бить мертвой лошади, но вы можете немного ускорить это, сделав теперь две перемены, которые стали для меня второй натурой. Во-первых, используйте map! вместо map, чтобы избежать создания копии разделенного массива, а во-вторых, чтобы избежать использования синтаксиса символа для proc (например, &: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)

Не забудьте прочитать номера относительно друг друга, а не относительно тестов, представленных в других ответах.

Ответ 5

Это не означает ответ на исходный вопрос, но я хотел бы поделиться эталонным кодом, чтобы люди могли проверить два предлагаемых решения для себя:

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

В моей системе (Ruby 2.0.0p247 на OS X 10.8), которая произвела следующий вывод:

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)

Эти результаты, конечно же, могут варьироваться между версиями рубинов, аппаратными средствами и ОС.

Ответ 6

Если я не ошибаюсь

things.split(", ")

было бы самым простым решением. Однако он работает только тогда, когда имеется ровно один пробел. (Обратите внимание на пробел после запятой)