The array toolbox

Changing the shape

Most array methods return a new array and leave the receiver alone. The exceptions carry a bang (map!, uniq!) or are the methods that push and pop. Two of the shape changers are worth knowing by name:

ruby -e 'p [1, [2, [3]]].flatten'

[1, 2, 3]

ruby -e 'p [1, nil, 2, nil].compact; p [1, 1, 2].uniq'

[1, 2]
[1, 2]

flatten goes all the way down; flatten(1) removes one level and keeps the rest. compact drops nil and keeps false, which matters when a list of booleans goes through it.

Set operations on arrays

Three operators treat arrays as sets. They remove duplicates and keep the order of the left side:

ruby -e 'p [1, 2] | [2, 3]'

[1, 2, 3]

ruby -e 'p [1, 2, 3] - [2]'

[1, 3]

ruby -e 'p [1, 2] & [2, 3]'

[2]

Each one is a linear scan under the hood, which is fine for tens of items. For thousands, the Set class, later in lesson 102, turns the same operations into hash lookups.

Working at both ends

A stack is a push and a pop; a queue is a push and a shift. Ruby uses one array for both:

ruby -e 'a = [1, 2, 3]; a.shift; a.push(4); p a'

[2, 3, 4]

ruby -e 'p [1, 2].zip(["a", "b"]); p [1, 2].product([:a, :b])'

[[1, "a"], [2, "b"]]
[[1, :a], [1, :b], [2, :a], [2, :b]]

zip pairs items by position and stops at the shorter side; product makes every combination. Both are the quick way to build rows before a each turns them into output.

What to watch for

A method without a bang returns a new array; the receiver is unchanged unless the name ends in ! or the method is push, pop, shift, unshift or []=. Assigning the result is the safe habit: names = names.compact.

| and & compare with eql? and hash, so two objects that are equal with == but not with eql? both survive the union. Lesson 87 has the difference.

Next: The hash toolbox

Article author: Arthur Isaev