Рубин: Сплит, а затем удалить ведущие/конечные пробелы на месте?
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(/,/)
Это делает большую часть того, что я хочу сделать, за исключением удаления ведущего/конечного пробела, когда он разбивается на запятую. Какой лучший способ достичь этого? Я хотел бы сделать это как часть этого выражения, вместо того, чтобы присваивать вышеупомянутый результат отдельному массиву и повторять его.
Ответы
Ответ 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(", ")
было бы самым простым решением. Однако он работает только тогда, когда имеется ровно один пробел.
(Обратите внимание на пробел после запятой)