2009-11-19 2 views
1

В Ruby у меня есть строка одинаковых символов - допустим, что они все восклицательные знаки, как в !!!!. Я хотел бы заменить символы в определенных индексах на «*», если целое число, соответствующее этому индексу, соответствует некоторым критериям.Замена символов в строке Ruby в соответствии с некоторым правилом

Например, я хочу заменить все символы, индексы которых являются четными числами и больше 3. В строке !!!!!!!! (длиной 8 символов), что приводит к !!!!*!*! (заменены индексы 4 и 6) ,

Какой самый компактный способ сделать это?

ответ

4

Вот версия, которая будет изменять существующую строку на месте:

str = '!!!!!!!!' 
str.split('').each_with_index do |ch, index| 
    str[index] = '*' if index % 2 == 0 and index > 3 
end 
0

Я новичок в Ruby, но я думал, что я хотел бы дать ему уйти. Ответ mikej намного лучше.

str = '!!!!!!!!' 
index = 0 
str.each_char { |char| 
     if (3 < index) && (index % 2 == 0) then 
       str[index] = '*' 
     end 
     index = index + 1 
} 

puts str 

РЕДАКТИРОВАТЬ

Вот немного лучшее решение, совмещая некоторые из других (было протестировано).

str = '!!!!!!!!' 
str.split('').each_with_index do |char, index| 3 < index and index % 2 == 0 ? str[index] = '*' : str[index] = char end 
puts str 
1

Я тоже новичок в Ruby, но функция enum_with_index попалась на глаза.

2nd Update: Это то, что я имел в виду. Этот код проверен.

"!!!!!!!".split('').enum_with_index.map{|c,i|(i%2==0 and i>3)?'*':c}.inject(""){|z,c|z+c} 
+0

Я получаю исходную строку, возвращенную при тестировании. не совсем уверен, как использовать инъекцию (я смотрю на нее). –

+0

Нет, если вы получаете исходную строку, то она не работает. Я не хочу тратить время. Через пару часов я смогу проверить это и исправить. –

+0

Сделано: Мое лучшее усилие, исправлено и протестировано сейчас. –

0

Возможно, самый компактный вы можете получить (более компактный, чем другие решения), но кто знает?

s="!!!!!!!!" 
4.step(s.length-1, 2) {|i| s[i]="*"} 
puts s 

Я бы также предположил, что это, пожалуй, самый эффективный, по сравнению с другими решениями.

2

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

str = '!!!!!!!!' 
res = '!!!!*!*!' 

str.replace(str.chars.with_index.inject('') { |s, (c, i)| 
    next s << c unless i%2 == 0 && i > 3 
    s << '*' 
}) 

require 'test/unit' 
class TestStringReplacement < Test::Unit::TestCase 
    def test_that_it_replaces_chars_at_even_indices_greater_than_3_with_asterisk 
    assert_equal res, str 
    end 
end 
+0

Выглядит круто, и, вероятно, работает лучше, чем у меня :) –

+0

Мне нравится, что вы включили тест с этим примером! – JohnMetta

0

как о регулярном выражении?

s="!!!!!!!!" 
puts s[0..3]+s[4..s.size].gsub(/!{2}/,"*!") 
Смежные вопросы