Last active
February 21, 2020 13:09
-
-
Save rpbaptist/e99a53d1c0c9c5d64a74cc9a042fd01f to your computer and use it in GitHub Desktop.
Spreadsheet column calculation in Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class XlsxColumns | |
attr_reader :position | |
ALPHABET = ("A".."Z").to_a | |
class << self | |
def column(position) | |
if position > max_position | |
raise ArgumentError, "Position must be #{max_position} or lower" | |
elsif position <= ALPHABET.length | |
letter_from_position(position) | |
else | |
letter_with_prefix(position) | |
end | |
end | |
private | |
def letter_with_prefix(position) | |
prefix_index = position / letter_count | |
adjusted_position = position % letter_count | |
prefix = letter_from_position(prefix_index) | |
letter = letter_from_position(adjusted_position) | |
prefix + letter | |
end | |
# It would be possible to make this recursive, but not really necessary. | |
def max_position | |
letter_count * letter_count | |
end | |
def letter_from_position(position) | |
ALPHABET[position - 1] | |
end | |
def letter_count | |
ALPHABET.length | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require "spec_helper" | |
require "xlsx_columns" | |
RSpec.describe XlsxColumns do | |
describe "#column" do | |
context "when position below 26" do | |
it "returns the corresponding letter" do | |
expect(described_class.column(3)).to eql("C") | |
expect(described_class.column(26)).to eql("Z") | |
end | |
end | |
context "when position is above 26" do | |
it "returns a combination of letters" do | |
expect(described_class.column(27)).to eql("AA") | |
expect(described_class.column(56)).to eql("BD") | |
expect(described_class.column(456)).to eql("QN") | |
expect(described_class.column(676)).to eql("ZZ") | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment