I want to get any string with a delimited string for each number of characters.

Asked 2 years ago, Updated 2 years ago, 42 views

In order to see the number of characters count, you want to create a string that replaces the desired string with a delimited string for each number of characters.

For example, if you want to include a delimiter every five characters, you can use □□□□□□□□□□□□□□□□□□□□ and as the delimiter.

□□□□■□□□□■□□□□■□□□□■
~~~~|~~~~|~~~~|~~~~
4+1 |4+1 |4+1 |4+1

and so on.

As an example of the above implementation, suppose you open the String class and create a new method similar to the following:

class String
   def step_replace(steps, replace_str)
     split_str=self.split(').each_slice(steps)
     range_max = steps-replace_str.length-1
     split_str.map { | x | x .slice(0..range_max) + [replace_str]}.join
   end
 end

At this time, this step_replace is available as follows:

 puts("Ayeo"*3).step_replace(5, "Hmm")
 # output: yomiireru

However, this step_replace feels redundant in that it processes strings arranged with split one by one.I felt that there was a more concise way to write, but what do you think?Or can't it be more concise?

ruby

2022-09-30 18:48

4 Answers

How about using regular expressions like this?

(The last as is to confirm that fractions are acceptable.)

irb(main): 001:0>("Ayeo"*3+"as").scan(/(.{1,3}).{,2}/).join("Yes")
=> "I'm sorry, I'm sorry, I'm sorry, I'm sorry, I'm sorry, I'm sorry."

This is a list like this in front of the join, and it's a join from there.

irb(main): 002:0>("Ayeo"*3+"as").scan(/(.{1,3}).{,2}/)
=>[["Ai"],["Ai"],["Ai"],["as"]]

If you want to apply variables, you can do the following

irb(main): 001:0>steps=5
=>5
irb(main): 002:0>replace_str = "Yes"
=>"Yes"
irb(main): 002:0>str_len=replace_str.length
=>2
irb(main): 008:0>("Ayeo"*3+"as").scan(/(.{1,#{steps-str_len}}}.{,#{str_len}}/).join(replace_str)
=> "I'm sorry, I'm sorry, I'm sorry, I'm sorry, I'm sorry, I'm sorry."

It's a bonus, but I think I can insert it below.

irb(main): 003:0>("Ayeo"*3).scan(/.{1,5}/).join("Yes")
=> "Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye


2022-09-30 18:48

The original code looks like the following, but I wrote it without worrying too much about the original code.

 puts("Aiueo"*3+"Ai").step_replace(5, "Hmm")
puts("Aiueo"*3+"Ai").step_replace(5, "Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm")
# >> Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye.
# >> Ai-en-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n.

I replaced it with String#chars because I thought split(') would reduce the feeling of processing into an array. Then, convert to an array of steps strings in chars.each_slice(steps).join(&:join) and click Edit as a string and combine.

class String
  def step_replace(steps, replace_str)
    chars.each_slice(steps).map(&:join).each {|s|
      s[s.size-replace_str.size..-1] = replace_strifs.size==steps
    }.join
  end
end
puts("Ayeo"*3+"Ai").step_replace(5, "Hmm")
puts("Aiueo"*3+"Ai").step_replace(5, "Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm")
# >> Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye
# >> Ai-en-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n-n.

replace_str.size is greater than steps, so it's better to do the following

class String
  def step_replace(steps, replace_str)#!>previous definition of step_replace was here
    chars.each_slice(steps).map(&:join).each {|s|
      s [[s.size-replace_str.size, 0].max,replace_str.size] = replace_strifs.size == steps
    }.join
  end
end
puts("Ayeo"*3+"Ai").step_replace(5, "Hmm")
puts("Aiueo"*3+"Ai").step_replace(5, "Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm")
# >> Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye
# >>Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

Why don't you use Numeric#step to find the location of the delimiter and replace the location characters and return them?

class String
  def step_replace(steps, replace_str)
    dup.tap {|s|
      replace_len=replace_str.size
      steps.step(size, steps) {|x|
        s[x-replace_len, replace_len] = replace_str
      }
    }
  end
end
puts("Ayeo"*3+"Ai").step_replace(5, "Hmm")
puts("Aiueo"*3+"Ai").step_replace(5, "Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm")
# >> Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye
# >>Aiennonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

However, if replace_str.size is greater than steps, the result is unintended.


2022-09-30 18:48

You cannot specify the number of characters separated by arguments, but how about replacing gsub with a back reference?

("Aiueo"*3).gsub(/(...)../, "\\1 Yes")
#=> "I'm sorry, I'm sorry"
("Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye
#=> "Aiunkaki kung-sashi"


2022-09-30 18:48

num = every few characters, char = delimiter

class CustomString <String  
    def replace_separator!(num,char)  
        self.size.times { | i | self[i] = char if(i+1)%num == 0}  
        self  
    end  
end  

str=CustomString.new('Aye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-ye-  
US>str.replace_separator! (5, '|')  
 => "Aiue | Aiue | Aiue | Kakikake | OK"  
US>str.replace_separator!(3, '|')  
 => "Ai | Eo | Say | Oh | Up | Scratch | Keiko |"  

In summary,

str.size.times {|i|str[i]='|'if(i+1)%5==0}

The string is specified only for the number of digits.
How about this one?


2022-09-30 18:48

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.