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

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

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

32
задан 29.03.2020, 00:55

6 ответов

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)
73
ответ дан 29.03.2020, 00:58
  • 1
    @Mahm00d и точка, в которой Вы абсолютно уверены Вы " больше не нужен database" когда Ваше приложение закрывается ОС. Так позвольте ОС обработать его для Вас.:) – Graham Borland 24.11.2019, 02:37
  • 2
    Обратите внимание на то, что это решение приблизительно в 2 раза медленнее, чем мой regex основывал тот. – Koraktor 29.03.2020, 00:58
  • 3
    @Koraktor После сравнительного тестирования, это похоже на Priti' s выполнения решения меньше чем в 60% времени Ваш подход regex требует. Я копировал обоих 1_000_000 времена с помощью Ruby 2.0p247 на OS X. I' d быть готовым отправить фактический код сравнительного теста, но выполнение так в комментарии сложно. – pjs 29.03.2020, 00:59
  • 4
    @pjs отправьте Ваш Сравнительный тест результат. – Arup Rakshit 29.03.2020, 00:59
  • 5
    Прекрасный. Спасибо очень! – Ben 29.03.2020, 00:59
  • 6
    @Koraktor Вы на самом деле синхронизировали его? Иногда Ruby удивляет меня. – pjs 29.03.2020, 01:00

Не бить мертвую лошадь, но вы можете ускорить это, сделав два изменения, которые теперь стали для меня второй натурой. Первый - использовать 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)

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

4
ответ дан 29.03.2020, 00:56
  • 1
    Что, если мы имеем массив строк и хотим простой вывод; как: String[] array = {"John", "Mahta", "Sara"}, и мы хотим этот вывод без скобки и запятых: John Mahta Sara? – Hengameh 18.10.2019, 16:48
  • 2
    Спасибо за ответ, it' s интересный видеть немного больше подробного синтаксиса, бьющего более краткий.:-) – Ben 29.03.2020, 00:57
  • 3
    @Ben Мое удовольствие. Более краткий обычно приравнивается к большему количеству " magic" и больше волшебства означает больше операции в секунду, и больше операции в секунду означает более медленную производительность:) – xentek 29.03.2020, 00:57

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

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)

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

2
ответ дан 29.03.2020, 00:57
  • 1
    Или начиная с Java 8 String.join(",", anArray), таким образом, нет никакой потребности во внешних библиотеках. – Pshemo 18.10.2019, 16:47
  • 2
    +1 для показа Вашего Сравнительный тест отчет. – Arup Rakshit 29.03.2020, 00:57

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

"one thing, two things, three things, four things".split /\s*,\s*/
# => ["one thing", "two things", "three things", "four things"]
7
ответ дан 29.03.2020, 00:58
  • 1
    Да я нашел, что открытие могло бы быть дорогим. Таким образом, если я понимаю Вас хороший, я должен сохранить соединение открытым. Но что, если пользователь перейдет к главному экрану. Я должен закрыть его в onPause () и открытый снова в onResume ()? Как я могу передать его между Намерениями? – Fixus 24.11.2019, 02:36

Как любитель скорости, я люблю тесты ... Но давайте посмотрим правде в глаза: если вы не выполняете эту операцию внутри миллиона циклов в вашем коде, различия в скорости, вероятно, не будут влиять на ваш код почти так же, как очевидные кодирующие конструкции.

По моему мнению, если производительность не имеет значения, у @arup есть лучшее, самое простое и ясное решение.

6
ответ дан 29.03.2020, 00:59
  • 1
    Когда я думаю строковое присоединение, я обычно думаю Строка, присоединяющаяся к разделителям, кроме очень определенных ситуаций. – TheLQ 18.10.2019, 16:47

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

things.split(", ")

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

2
ответ дан 29.03.2020, 01:00
  • 1
    That' s действительно хорошая библиотека! – Lukas Eder 18.10.2019, 16:48

Теги

Похожие вопросы