Reputation:
I have a string:
key = "41521"
And I want to convert it into an array like this:
array = [41, 15, 52, 21]
I went about it like so:
array = []
array << key[0..1].to_i
array << key[1..2].to_i
array << key[2..3].to_i
array << key[3..4].to_i
What would be a better way?
Upvotes: 0
Views: 131
Reputation: 110755
key = "41521"
key.each_char.each_cons(2).map { |a| a.join.to_i }
#=> [41, 15, 52, 21]
or
key.gsub(/\d(?=(\d))/).with_object([]) { |s,a| a << (s<<$1).to_i }
#=> [41, 15, 52, 21]
or
a = []
e = key.each_char
#=> #<Enumerator: "41521":each_char>
loop { a << (e.next << e.peek).to_i }
a #=> [41, 15, 52, 21]
In #3 Enumerator#peek raises a StopInteration
exception when the internal position of the enumerator is at the end (unless key
is an empty string, in which case Enumerator#next raises the StopInteration
exception). Kernel#loop handles the exception by breaking out of the loop.
Upvotes: 6
Reputation: 42169
Not as short as some other answers, but for me, more easier to see the steps:
arr = key.chars.each_with_index
.reduce([]) {|s,(v,i)| s << (v + (key[i+1] || '')).to_i }
.select {|s| s.to_s.length > 1 }
# arr: [41, 15, 52, 21]
Upvotes: 1
Reputation: 168259
key.gsub(/(?<=.)\d(?=.)/, '\&\&').scan(/\d{2}/).map(&:to_i)
# => [41, 15, 52, 21]
or
(0...key.length).map{|i| key[i, 2].to_i}
# => [41, 15, 52, 21, 1]
Upvotes: 2