Recently I was working on a CLI application (nothing crazy, just a fun little Superhero API project), and I wanted to spruce up the way I was outputting my list of all the available heroes.
I'm still new to programming, so I try to focus on function over form as much as possible while I'm learning. I'm also not trying to shout from the rooftops about my training wheels though, you know?
And that'd pretty much what this feels like:
...pretty rough, especially considering there are over 700 characters in that list.
So obviously I needed to take advantage of a little more horizontal real estate, but I was having trouble finding a straight-forward way to accomplish that without really knowing what to search for. I get that there are tons of command line tools out there that will format everything up and make it look dynamite, but I'm trying to learn the fundamentals. What's a guy gotta do to get a basic column out here??
So that brings us here, to .rjust
and .ljust
, two super easy methods (which for some reason are hiding in the comments of Stack Overflow with not enough upvotes) to help format your output into columns in regular ol' Ruby.
As you probably guessed, those stand for 'right justify' and 'left justify', and there are a couple key things to note here if you're having trouble using them.
These methods take an argument for the desired length of the new string not how much whitespace to add
If you try an example in IRB, you can see that .rjust
is actually just padding the left side of the string and .ljust
is padding the right ride of the string:
:001 > "apple".rjust(10)
=> " apple"
:002 > a = "apple".ljust(10)
=> "apple "
:003 > a.length
=> 10
These methods also take the optional second argument of a string to use for padding instead of whitespace
:004 > "banana".rjust(10, "*")
=> "****banana"
# You can also use a pattern for padding
:005 > "apple".rjust(20, "!?") + "peach".rjust(20, " -")
=> "!?!?!?!?!?!?!?!apple - - - - - - - peach"
Honestly, I can't think of too many practical applications for using something other than whitespace, but at least we're getting closer to understanding how to build out our columns.
NOTE: Make sure you aren't asking your string to be shorter than it started.
Calling "Grapefruits".rjust(10)
isn't going to get you anywhere, because you're telling an 11 character string to pad itself on the left with enough spaces to become a 10 character string...
Now, if you're working with an array of arrays, this is pretty much as far as you need to go, since it's easy enough to iterate over your group and right or left justify each one.
dynamic_duos = [ ["Tom", "Jerry", "1940"], ["Scooby", "Shaggy", "1969"], ["Ketchup", "Mustard", "1812"] ]
dynamic_duos.each{ |duo|
puts duo[0].rjust(10) + duo[1].rjust(10) + duo[2].rjust(10)
}
# Prints these columns
Tom Jerry 1940
Scooby Shaggy 1969
Ketchup Mustard 1812
Not bad! Why are my years strings though? That's not very realistic, especially if I wanted to order my columns by year or something. That's because of the second common mistake with these methods.
.rjust
and .ljust
are methods from the String class
Calling these methods on an integer (like those years up there should be) will raise an error, but this actually isn't a big deal. There are plenty of easy solutions, like...
Interpolation
dynamic_duos = [ ["Tom", "Jerry", 1940], ["Scooby", "Shaggy", 1969], ["Ketchup", "Mustard", 1812] ]
dynamic_duos.each{ |duo| puts duo[0].rjust(10) + duo[1].rjust(10) + "#{duo[2]}".rjust(10)}
# Prints the same columns from before
Tom Jerry 1940
Scooby Shaggy 1969
Ketchup Mustard 1812
If your arrays have a mixture of data types, you can interpolate all of the elements to be safe. There are lots of other options, like explicitly converting your value to a string first with .to_s.rjust(10)
, but I won't get into all those here.
What if I'm working with a normal array?
That's right, I almost forgot that the whole reason we're doing this is to print out a list of 731 superheroes without making our users scroll for five straight minutes.
Here's a shorter example of what I ended up doing:
fifteen_hockey_players = ["Lemieux", "Crosby", "Jágr", "Malkin", "Fleury", "Murray", "Jarry", "Letang", "Kessel", "Guentzel", "Rust", "McCann", "Dumoulin", "Hagelin", "Pettersson"]
# Totally not biased for any particular team
count = 0
number = (fifteen_hockey_players.length/3)
# Divided by three because I want three columns
number.times do
puts fifteen_hockey_players[count].rjust(15) + fifteen_hockey_players[count+1].rjust(15) + fifteen_hockey_players[count+2].rjust(15)
count += 3
end
# Prints these lovely, lovely columns
Lemieux Crosby Jágr
Malkin Fleury Murray
Jarry Letang Kessel
Guentzel Rust McCann
Dumoulin Hagelin Pettersson
As long as I up my counter by the number of columns I have, I can print out as long a list as I like, in as many columns as I like.
Thanks to everyone who read this far! It's a little long, but I hope this will help some people like myself, who didn't have much experience with .rjust
and .ljust
. If anyone has anything to add or critique, please let me know in the comments.
Things to play around with on your own if you're interested: .center
, chaining .rjust.ljust
, and using the length of your string as the argument ex. .rjust(x.length + 5)
.
Top comments (0)