Article Series

This article series discuss more than 30 different programming languages. Please read overview before you read any of the details.

Playing with Records Related Articles.

Where to Discuss?

Local Group

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.

Ruby: Struct in Ruby

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

Ruby: The Songs Module Containing List of Struct

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: Using Songs Module

❯ 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"]

Ruby: Solving Unique Song

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 ].