2014-11-20 7 views
0

Это довольно простой, но я не уверен, как это сделать, если я не использую массив внутри карты, который является хромым.Карта dont proccess, если условие истинно

Мне нужно, чтобы получить это:

"T--- is my d-- b-- n-- y---" 

Если есть два символа, мне нужно, чтобы пропустить его, не обрабатывать его, но по-прежнему держать его. Если я использую next, я получаю нуль.

str = "This is my day but not your" 

str.split.map{ |word| word[0] + word[1..-1].gsub(/./,"-")} * " " #=> T--- i- m- d-- b-- n-- y--- 

Это мое второе решение, которое мне не нравится, но это работает, я уверен, что есть более элегантное решение:

arr = Array.new 
str.split.map{ |word| 
arr << word if word.length < 3 
arr << word[0] + word[1..-1].gsub(/./,"-")} * " " 

puts arr.join(" ") 
+0

Что произойдет, если слово является одним символом, например «a» или «I»? –

+0

Спасибо за вклад TinMan, мне нравится ваше решение. Если слово является одиночным символом, оно не будет заменено, и я не хочу, чтобы это было. – BulletTime

ответ

0

Вобще тождественное отображение на случаи, когда не хочу ничего делать.

str.split.map{ |word| 
    if word.length == 2 
    word 
    else 
    word[0] + word[1..-1].gsub(/./,"-") 
    end 
} * " " 

Если вам нужен один вкладыш:

str.split.map{ |word| word.length == 2 ? word : word[0] + word[1..-1].gsub(/./,"-")} * " " 
+0

Это швы Я не понимаю карты, спасибо! Я придумал это. str.split.map {| word | слово, если word.length <3; слово [0] + слово [1 ..- 1] .gsub (/./,"- ")} *" " – BulletTime

0

Я хотел бы сделать это:

str = "This is my day but not your" 
ary = str.split.map{ |s| 
    if s.size != 2 
    s[0] + '-' * (s.size - 1) 
    else 
    s 
    end 
} 

Вот что ary выглядит следующим образом:

ary 
# => ["T---", "is", "my", "d--", "b--", "n--", "y---"] 

join в массивы t о воссоздавать строку:

ary.join(' ') 
# => "T--- is my d-- b-- n-- y---" 

Что произойдет, если слово один символ, например, «а» или «I»?

Если слово является единственным символом, оно не будет заменено, и я не хочу, чтобы это было.

str = "This is my day but not your a" 
ary = str.split.map{ |s| 
    if s.size > 2 
    s[0] + '-' * (s.size - 1) 
    else 
    s 
    end 
} 

ary 
# => ["T---", "is", "my", "d--", "b--", "n--", "y---", "a"] 

ary.join(' ') 
# => "T--- is my d-- b-- n-- y--- a" 
+0

Это потрясающе, пару месяцев назад, если кто-то сказал мне, что я буду восхищаться кодом, я бы, хотя он сумасшедший. – BulletTime

+0

«Элегантность» - это концепция программирования, которая проста, легко читается, но при этом мощна. Я не претендую на то, чтобы писать элегантный код, но я стараюсь. Я обнаружил, что Ruby придает себя элегантности. –

0

Вы можете использовать более конкретное регулярное выражение gsub на строку в целом, так что вы только обрабатывать слова из трех символов или дольше.

str.gsub(/\w{3,}/) do |word| 
word[0]<<word[1..-1].gsub(/./,'-')} 
end 

В наружном gsub, \w относится к любому «слово» характер (в основном, буквы и цифры). {3,} означает повторение по меньшей мере 3 раза. В блоке мы делаем еще один gsub для обработки отдельного слова.

Возможно, вы можете сделать это в одном gsub, используя сложное регулярное выражение с lookbehind и lookahead, но это похоже на перебор.

0

Ваш вопрос не очень понятно, о том, что правила для замены, но предполагается, что ваши правила:

  1. печати любое слово с двумя или менее буквами без изменений.
  2. Заменить все символы, кроме первой буквы каждого оставшегося слова, с помощью подчеркивания.

С этими правилами, вы можете сделать это с кодом, как следующее:

str = 'This is my day but not yours' 
str.split.map do |word| 
    underscores = ?_ * (word.size - 1) 
    word.size < 3 ? word : word.gsub(/\A.\K.*/, underscores) 
end.join " " 
#=> "T___ is my d__ b__ n__ y____" 

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

Смежные вопросы