You Pick ’em! Selecting with Arrays

Selecting items from an Array isn’t much different that iterating over one in that it also requires a code block. Instead of communicating with or changing an item, we’re only giving selection criteria. The docs split these method groups into two areas, Non-destructive and Destructive, which I will also follow.

Non-destructive Selection


If you’re the kind of person that knows what you want, disperse your criteria through #select. Expect to die alone an empty array if your desires cannot be met.

snowball = ["I", "made", "myself", "a", "snowball"] {|word| word.include?("m")}
=> ["made", "myself"] {|word| word.include?("z")}
=> []

If you know what you want, but you’re not in the mood to communicate it, then expect an Enumerator to be spat back in your face. It’s generally a good idea to communicate things in life.

snowball = ["I", "made", "myself", "a", "snowball"]
=> #<Enumerator: ["I", "made", "myself", "a", "snowball"]:select>


If you’re ever at a place in life where you don’t know what you want, then it’s completely acceptable to lay out what you don’t want. In that case, you’ll want #reject. Bonus points if you are able to actually remove the desire for perfection.

snowball = ["as", "perfect", "as", "could", "be"]

snowball.reject {|word| word.include?("perfect")}
=> ["as", "as", "could", "be"]

snowball.reject {|word| word.include?("expectations")}
=> ["as", "perfect", "as", "could", "be"]

Same rules apply if you don’t pass a block with your criteria to #reject. If you’re the type that goes around rejecting without cause, then I want you to know that “ghosting” is a terrible hobby.

snowball = ["as", "perfect", "as", "could", "be"]

=> #<Enumerator: ["as", "perfect", "as", "could", "be"]:reject>


There’s a Snoop Dogg joke to be made here about dropping things while they are hot, but let’s stay focused on snowballs while they are still cold. If the order of items in the array matters, this is a good time to consider #drop_while. As soon as an object returns false or nil within your criteria block, we get a new array with this item and each after it.

In this initial example, the first item returns false, so we get an array that appears identical, but is technically a new one since this does not modify the original. If we flip the sign, then “thought” is the first to return false, so “I” is the only one that gets dropped.

snowball = ["I", "thought", "I'd", "keep", "it", "as", "a", "pet"]

snowball.drop_while {|word| (word.length) > 2}
=> ["I", "thought", "I'd", "keep", "it", "as", "a", "pet"]

snowball.drop_while {|word| (word.length) < 2}
=> ["thought", "I'd", "keep", "it", "as", "a", "pet"]

Same rules apply if you don’t pass a block.

snowball = ["I", "thought", "I'd", "keep", "it", "as", "a", "pet"]

=> #<Enumerator: ["I", "thought", "I'd", "keep", "it", "as", "a", "pet"]:drop_while>

This could be more useful with numeric data if, say, you had the daily recorded high temperatures and wanted to get every day’s recording until the high hit 75. Or if you wanted to butcher a poem and chop off the first three words.

snowball = ["I", "thought", "I'd", "keep", "it", "as", "a", "pet"]

snowball.drop_while.with_index {|word, index| index < 3}
=> ["keep", "it", "as", "a", "pet"]


Destructive Selection

Let’s toss aside the peacekeeping and get some destruction going with a bang (!). We could also consider this up-cycling. Why create a new array object when we can forever modify the old one?


If you’re the kind of person that knows what you want and won’t have a use for the original array, then use #select! When you’re this harsh, though, expect nothing in return if, in fact, your standards are too high nothing meets your criteria.

snowball = ["and", "let", "it", "sleep", "with", "me"]! {|word| word.include?("t")}
=> ["let", "it", "with"] {|word| word.include?("z")}
=> []

=> []


Destructive rejection sounds like a wonderful childhood experience. Be aware if nothing is rejected, then you will get a nil object in return as there won’t be anything to modify with your original array.

snowball = ["I", "made", "it", "some", "pajamas"]
snowball.reject! {|word| word.include?("perfection")}
=> nil

=> ["I", "made", "it", "some", "pajamas"]

snowball.reject! {|word| word.include?("p")}
=> ["I", "made", "it", "some"]


If you want to reject destructively without fear of being given a nil object, #delete_if is here to help.  It will return the unchanged array if there’s nothing to discard.

snowball = ["and", "a", "pillow", "for", "its", "head"]
snowball.delete_if {|word| word.include?("perfection")}
=> ["and", "a", "pillow", "for", "its", "head"]

=> ["and", "a", "pillow", "for", "its", "head"]

snowball.delete_if {|word| word.include?("p")}
=> ["and", "a", "for", "its", "head"]


The other side of the #delete_if coin is #keep_if, which is a counterpart to #select!

snowball = ["then", "last", "night", "it", "ran", "away"]
snowball.keep_if {|word| word.include?("n")}
=> ["then", "night", "ran"]

=> ["then", "night", "ran"]

snowball.keep_if {|word| word.include?("perfection")}
=> []

=> []

Today’s lorem ipsum is brought to us by the late Shel Silverstein and his poem, “Snowball”

I made myself a snowball
As perfect as could be.
I thought I’d keep it as a pet
And let it sleep with me.
I made it some pajamas
And a pillow for its head.
Then last night it ran away,
But first—it wet the bed.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s