Замена символов в строке Ruby согласно некоторому правилу - PullRequest
1 голос
/ 19 ноября 2009

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

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

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

Ответы [ 6 ]

4 голосов
/ 19 ноября 2009

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

str = '!!!!!!!!'
str.split('').each_with_index do |ch, index|
  str[index] = '*' if index % 2 == 0 and index > 3
end
2 голосов
/ 19 ноября 2009

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

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
1 голос
/ 19 ноября 2009

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

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

"!!!!!!!".split('').enum_with_index.map{|c,i|(i%2==0 and i>3)?'*':c}.inject(""){|z,c|z+c}
0 голосов
/ 19 ноября 2009

как насчет регулярных выражений?

s="!!!!!!!!" 
puts s[0..3]+s[4..s.size].gsub(/!{2}/,"*!")
0 голосов
/ 19 ноября 2009

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

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

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

0 голосов
/ 19 ноября 2009

Я новичок в ruby, но я решил попробовать. Микей ответ гораздо лучше.

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

puts str

EDIT

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

str = '!!!!!!!!'
str.split('').each_with_index do |char, index| 3 < index and index % 2 == 0 ? str[index] = '*' : str[index] = char end
puts str
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...