Вопрос по ruby-on-rails, arrays, ruby – Как улучшить код, который цитирует все элементы массива с помощью `'` и возвращает строку, содержащую все эти элементы в кавычках и через запятую?

9

Я использую Rails 3.2.2, и я хотел бы процитировать все элементы массива с' и вернуть строку, содержащую все эти элементы в кавычках и через запятую. В настоящее время я использую

['a', 'b', 'c'].collect {|x| "'#{x}'"}.join(", ")
# => "'a', 'b', 'c'"

но я думаю, что могу улучшить приведенный выше код (возможно, используя неизвестный мне метод Ruby, если он существует). Является ли это возможным?

То, что у тебя есть, кажется мне хорошим. Andrew Marshall
То, что у тебя есть, хорошо. Кроме того, это чистый рубин. Нет ничего "рельсов" об этом. Dty
@ Холгер Просто - Опс! Backo
Нет ничего для оптимизации, но вы можете использовать псевдонимы:map вместоcollect а также* вместоjoin если вам не хватает кода, чтобы уменьшить размер кода:%w[a b c].map{|x|"'#{x}'"}*', '. jdoe
Что произойдет, если одна из строк в массиве содержит' сам по себе, например["a", "b'cd"]? Holger Just

Ваш Ответ

2   ответа
11

"'#{%w{a b c}.join("', '")}'"

Вот расширенная версия:

' # Starting quote
%w{a b c}.join("', '") # Join array with ', ' delimiter that would give a', 'b', 'c
' # Closing quote
Кажетсяyour version performs better.
Вы можете включить это в свой ответ, чтобы объяснить, почему ваш код предпочтительнее. Кроме того, вы имеете в виду сборку мусора с помощью "GC"?
И вот почему: прежде всего, он обходит массив один раз, а не два (сопоставление и объединение). Во-вторых, он создает меньше объектов ruby - одну строку-обертку для фактического результата и одну строку в качестве результата соединения. Исходное решение создает новый массив для результата карты и новую строку для каждого элемента в массиве. Это может показать ухудшение производительности на большем массиве, так как GC займет больше времени.
6

collect с его псевдонимомmap а также.join с эквивалентным*, Наконец, вы можете использоватьярлык для записи массива строк, %w(...)и вы можете использовать одинарные кавычки для аргумента.join/* поскольку он не использует интерполяцию строк (хотя это может быть сомнительным, если это предпочтительнокогда дело доходит до производительности).

%w(a b c).map {|x| "'#{x}'"} * ', '

Похоже, что нет разницы в производительности между этой версией и оригиналом, но что этоВерсия Сигурда работает лучше:

Original  3.620000   0.000000   3.620000 (  3.632081)
This  3.640000   0.000000   3.640000 (  3.651763)
Sigurd's  2.300000   0.000000   2.300000 (  2.303195)

Код для бенчмарка:

require 'benchmark'

n = 1000000

Benchmark.bm do |x|
  x.report("Original") { n.times do
      ['a', 'b', 'c'].collect {|x| "'#{x}'"}.join(", ")
    end}
  x.report("This") { n.times do
      %w(a b c).map {|x| "'#{x}'"} * ', '
    end}
  x.report("Sigurd's") { n.times do
      "'#{%w{a b c}.join("', '")}'"
    end}
end

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