Give your code some breathing room. I.e. ) { |a, b|
instead of ){|a, b|
. And there's no need to put everything on one line. The way your block works right now, it'd be better to store the result of pwn.split
in a variable, instead of calling split
twice. (There's also no need to abbrevate "pawn" as "pwn".)
That being said, strings support array-like access, so you don't need the split
at all.
Judging from your code, pawns
is an array. Transforming an n-element array to a new n-element array is called "mapping". You're using inject
which is also known as reduce
(and fold
in many other languages; see comments) - an operation most often used to take an n-element array and reduce it to a single value. So step 1: Use map
instead of inject
.
I'd probably use a regex to pull the string apart. It'll double as a way to check the coordinate strings for validity (e.g. so no "z9" coordinates will slip through).
It's a little low-level, but we can use the fact that "a" is 97 in ASCII. So to get the number for a letter, we can say letter.ord - 96
.
You get something like this:
def safe_pawns(squares)
squares.map do |square|
[$1.ord - 96, $2.to_i] if square.downcase =~ /^([a-h])([1-8])$/
end.compact
end
Alternatively, if you're sure that all the input coordinates are valid, lowercase strings already, you don't need the regex or the downcasing:
def safe_pawns(squares)
squares.map { |square| [square[0].ord - 96, square[1].to_i] }
end
As tokland points out in the comments, we can avoid the hardcoded 96
(which isn't very self-explanatory) and instead get the letter-to-number translation by saying:
square[0].ord - 'a'.ord + 1