'Incrementing letters using .next
def home
letter = 'A'
@markers = Location.all.to_gmaps4rails do |loc, marker|
marker.infowindow render_to_string(partial: '/locations/info',
locals: {object: loc})
marker.picture({picture: "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=#{letter.next!}|9966FF|000000",
width: 32,
height: 32,
shadow_picture: "http://chart.apis.google.com/chart?chst=d_map_pin_shadow",
shadow_width: 110,
shadow_height: 110,
shadow_anchor: [17,36]})
marker.title "Title - #{loc.name}"
marker.sidebar render_to_string(partial: '/locations/sidebar',
locals: {object: loc})
marker.json({id: loc.id})
end
end
Cool stuff. So this works. It cycles through the do loop
and increments the letter. Problem is, it starts at B. I tried using just letter
in the picture, then at the end using letter.next!
, and even letter = letter.next
, but gmaps throws an error at me.
Is there a way to assign something besides 'A' to letter
?
Solution 1:[1]
This works, but I'll second @patrick-oscity in that it is arguably obscure:
letter = '@'
letter.next! #=> "A"
Another solution is mutating the letter at the end of the loop, after using it.
This snippet:
letter = 'A'
1.upto(5) do
puts letter
letter.next!
end
... produces this output:
A
B
C
D
E
Solution 2:[2]
Well technically, '@'
is the predecessor of 'A'
, because the ASCII value of '@'
is 64 and the value of 'A'
is 65. Observe:
'A'.codepoints.first
#=> 65
'A'.codepoints.first - 1
#=> 64
('A'.codepoints.first - 1).chr
#=> "@"
('A'.codepoints.first - 1).chr.next
#=> "A"
in that sense:
'@'.next == 'A'
#=> true
but i strongly discourage the use of black magicâ„¢. Use something like @nicooga's approach in real code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Patrick Oscity |