How to Iterate Over String Taking Each Nth Char?

Crystal newbie here. So go easy on me!

I’m trying to iterate over a string, getting each nth [in this particular case 3rd] character. I can’t get beyond the basic iteration:

blurb = "some incredibly tedious oul text an all thon"

blurb.each_char do |char|
  puts "here's a character  --> #{char}"
end

I thought maybe I could throw a step() in there. But the compiler didn’t like it:
SS 2021-03-09 at 19.13.40

So, can someone tell me where I’m going wrong, please? I’m probably missing something really obvious. But this is all new to me.

The problem is .step(3) is returning another Iterator. So you would need to do something like:

blurb = "some incredibly tedious oul text an all thon"

blurb.each_char.step(3).each do |char|
  puts "here's a character  --> #{char}"
end

EDIT: One thing worth pointing out is the semantics of String#each_char is different depending on if you give it a block or not. If you do give it a block, it’ll yield for each char, otherwise it returns an Iterator instance that needs another method call, e.g. .each to actually do the iteration.

Aha! As simple as that, eh?

Thanks!

Here’s a similar way.

blurb = "some incredibly tedious oul text an all thon"

blurb.each_char_with_index do |char, i|
  puts "here's a character  --> #{char}" if i.divisible_by?(3)
end
1 Like

That being said, it feels inconsistent that .each_char takes a block, but step doesn’t. I feel like any method that returns an iterator should also have a version that takes a block for consistency.

Yes, Enumerable misses an equivialent enumeration method to Iterator#step