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.inspect
With 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 end
With 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 end
With 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 ].