1

I'm working on a problem where I am given a "coded" message in the form of a string, and have to return the decoded message. This requires me to split a string of mixed characters and numbers into an array. So for example, if I got a string like this:

"0h"

I want to split it into an array like this:

[0, "h"]

But when I use .split I get

["0", "h"]

The solutions I have found only take into account strings that are all numbers, but not mixed strings. Is there a way to convert the strings that are numbers into numbers while retaining the characters?

2 Answers 2

4

You can use String#scan with a regular expression.

str = "0hh1ghi22d"

str.scan(/\d+|\D+/).map { |s| s =~ /\d+/ ? s.to_i : s }
  #=> [0, "hh", 1, "ghi", 22, "d"]

or

str.each_char.map { |s| s =~ /\d/ ? s.to_i : s }
  #=> [0, "h", "h", 1, "g", "h", "i", 2, 2, "d"]

depending on requirements.

Sign up to request clarification or add additional context in comments.

7 Comments

chars as the first part also works if individual characters are desired.
@tadman, good suggestion, as the question is not clear on that. I did an edit.
You can avoid matching \d+ twice by using capture groups: str.scan(/(\D+)|(\d+)/).map { |s, d| s || d.to_i } (note that I've changed the order of \D+ and \d+)
@Stefan, that's lovely,but I don't understand why you needed to change the order of \d+ and \D+. Readers, if you don't follow Stefan's code, note that str.scan(/(\D+)|(\d+)/) #=> [[nil, "0"], ["hh", nil], [nil, "1"], ["ghi", nil], [nil, "22"], ["d", nil]].
Thank you! This worked great. Just so I know I understand what's happening since I'm really new at maps, it's passing each character to a block, seeing if the character is a number and if it is it converts it to an integer. Is that what /\d/ does? Just want to make sure I understand the logic of it. Thanks a lot for the help!
|
1

If I understand you correctly, you want to have digits in the string end up as Fixnums in your array.

You can do this by adding a .map to your split:

... .map { |c| c =~ /\d/ ? c.to_i : c }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.