Preface
Goal: A practical case to collect unique record fields using Ruby.
Preface
Goal: Continue Part One
4: Data Structure Using Struct
There is other alternative data structure as well.
Instead of hash, we can use struct.
Struct
The declaration is simple.
Song = Struct.new(:title, :tags)
song = Song.new('Cantaloupe Island', ['60s', 'jazz'])
puts song.inspectWith the result as below:
❯ ruby 12-song.rb
#<struct Song title="Cantaloupe Island", tags=["60s", "jazz"]>we can examine the struct object, shown in output result above.

The Songs Structure
Just like using hash,
we can continue our journey to records just using struct.
No need any complex structure.
Song = Struct.new(:title, :tags) do
def value
"#{title}: #{tags}"
end
end
songs = [
Song.new('Cantaloupe Island',
['60s', 'jazz']),
Song.new('Let It Be', ['60s', 'rock']),
Song.new('Knockin\' on Heaven\'s Door',
['70s', 'rock']),
Song.new('Emotion', ['60s', 'jazz']),
Song.new('The River')
]
songs.each do |song| puts song.value endWith the result similar as below record:
❯ ruby 13-songs.rb
Cantaloupe Island: ["60s", "jazz"]
Let It Be: ["60s", "rock"]
Knockin' on Heaven's Door: ["70s", "rock"]
Emotion: ["60s", "jazz"]
The River: 5: Separating Module
Again, we need to reuse the songs struct multiple times, so we separate the record structure from logic.
Songs Module
The code can be shown as below:
module StructSongs
Song = Struct.new(:title, :tags) do
def value
"#{title}: #{tags}"
end
end
SONGS = [
Song.new('Cantaloupe Island',
['60s', 'jazz']),
Song.new('Let It Be', ['60s', 'rock']),
Song.new('Knockin\' on Heaven\'s Door',
['70s', 'rock']),
Song.new('Emotion', ['60s', 'jazz']),
Song.new('The River')
]
end
Using Songs Module
Now we can have a very short code.
require_relative 'MyStructSongs'
include StructSongs
SONGS.each do |song| puts song.value endWith the result as below.

❯ ruby 14-module.rb
Cantaloupe Island: ["60s", "jazz"]
Let It Be: ["60s", "rock"]
Knockin' on Heaven's Door: ["70s", "rock"]
Emotion: ["60s", "jazz"]
The River: Notice how the last song handle nil value.
3: Finishing The Task
Map, Compact, Flatten, Unique
Method Chaining
All works in array.
Finally we solve unique list
require_relative 'MyStructSongs'
include StructSongs
tagss = SONGS
.map { |song| song.tags }
.compact
.flatten
.uniq
puts "#{tagss}"With the result similar as below array:
❯ ruby 15-map.rb
["60s", "jazz", "rock", "70s"]
Even tidier with dot.
What is Next 🤔?
We have alternative way to do get unique list. And we will also discuss about concurrency.
Consider continue reading [ Ruby - Playing with Records - Part Three ].