Использование #inject для объединения строк из массива - PullRequest
9 голосов
/ 14 марта 2012

Я прохожу онлайн-урок , который обычно имеет очень простое однострочное решение.Проблема состоит в том, что при наличии следующего массива:

["emperor", "joshua", "abraham", "norton"]

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

"Emperor Joshua Abraham Norton"

Хотя это легко можно сделать с помощью #map и #join, в этом конкретном упражнении необходимо использовать только #inject.Я придумал что-то вроде этого:

["emperor", "joshua", "abraham", "norton"].inject("") do |memo, word|
   memo << word.capitalize << " "
end

, который дал бы мне:

"Emperor Joshua Abraham Norton "

, где пробелы в конце строки не проходят как правильное решение.

  • Как мне добиться этого без пробела в конце?
  • Это даже правильный способ использовать #inject, пропуская пустую строку?
  • AmЯ правильно использую << для объединения строк?

Ответы [ 6 ]

8 голосов
/ 14 марта 2012

Попробуйте это:

a.map{|t| t.capitalize}.join(" ")

Я не думаю, что вы можете сбежать из лишнего пространства с помощью инъекции. Также вам нужно сделать

memo = memo + word.capitalize + " " 

РЕДАКТИРОВАТЬ: так как выражение изменилось, чтобы заставить вас не использовать объединение и сопоставление, вот несколько уродливое решение с inject:

a.inject("") do |memo, world|
  memo << " " unless memo.empty?
  memo << word.capitalize
end
2 голосов
/ 14 марта 2012
a = ["emperor", "joshua", "abraham", "norton"]
a.drop(1).inject(a.first.capitalize){|res,m| res << ' '+m.capitalize }
1 голос
/ 14 марта 2012

Проверка добавления " " каждого хода дороже, чем chop! последнего выхода.Ваш выбор в отношении << верен, вы можете посмотреть объединение строк .

irb(main):021:0> %w(emperor joshua abraham norton).inject("") do |m,w|
                     m << w.capitalize << " "
                   end.chop!
"Emperor Joshua Abraham Norton"
1 голос
/ 14 марта 2012

Есть лучшие способы, чем #inject, см. Другие ответы. Но если вы настаиваете, вы можете просто String#rstrip символ пробела в конце.

Или переверните блок и проверьте, пусто ли памятка перед добавлением символа.

memo << " " unless memo.empty?
memo << name.capitalize

Я не уверен насчет оператора <<. Я бы использовал +, но это, вероятно, просто личное предпочтение.

0 голосов
/ 12 августа 2015

помещает x.inject {| memo, val |"# {memo} # {val.upcase}"}

0 голосов
/ 14 марта 2012

Не используйте #inject, есть лучшие способы решить это:

["emperor", "joshua", "abraham", "norton"].map(&:capitalize).join(' ')

Ваша первая цель всегда должна заключаться в решении проблемы под рукой.Вы могли бы использовать #inject, но это просто не идеальное или даже ясное решение здесь.У вас есть дела поважнее, чем пытаться придумать, как обмануть #inject, чтобы дать вам правильный результат.

...