Ruby Tuesday – Array#compact

Today’s Ruby Tuesday in on Array#compact.

Array#compact operates against a given array and returns a new array with any nils removed.

array1 = [1, 2, nil, 3, nil, nil, 4, nil]
# => [1, 2, nil, 3, nil, nil, 4, nil]
array2 = array1.compact
# => [1, 2, 3, 4]
array1
# => [1, 2, nil, 3, nil, nil, 4, nil]
array2
# => [1, 2, 3, 4]
Array.new(7)
# => [nil, nil, nil, nil, nil, nil, nil]
Array.new(7).compact
# => []
[].compact
# => []
array_with_no_nils = [1, 2, 3, 4, 5]
# => [1, 2, 3, 4, 5]
compacted_array_with_no_nils = array_with_no_nils.compact
# => [1, 2, 3, 4, 5]
compacted_array_with_no_nils
# => [1, 2, 3, 4, 5]
array_with_no_nils
# => [1, 2, 3, 4, 5]

As seen in the examples above, Array#compact preserves the original order of the elements in the source array.

Array#compact only performs a shallow removal of any nils, and does not remove nils from any nested arrays.

mixed_type_array = [nil, :a, nil, nil, "b", [1, 2, nil, 3], nil, :c]
# => [nil, :a, nil, nil, "b", [1, 2, nil, 3], nil, :c]
mixed_type_array.compact
# => [:a, "b", [1, 2, nil, 3], :c]

And because nils in Ruby are falsey, we can do a quick sanity check about if Array#compact is looking at nils specifically, or falsey items in general, by creating a new Array filled with falses and calling compact on it.

Array.new(9){false}.compact
=> [false, false, false, false, false, false, false, false, false]

The Array class also defines Array#compact!, which modifies the underlying state of the Array it is being called on.

array3 = array1.dup
# => [1, 2, nil, 3, nil, nil, 4, nil]
array4 = array3.compact!
# => [1, 2, 3, 4]
array3
# => [1, 2, 3, 4]
array4
# => [1, 2, 3, 4]

As we can see in the above example, if the array compact! is being called on does have nils in it, the return value is the modified state of the Array.

But if you call Array#compact! on an array that does not have any nils in it, the return value of Array#compact! is nil.

Array.new(9){false}.compact!
# => nil

–Proctor