
December 4, 2024
Introduction
Ruby arrays are a versatile and powerful data structure, but sometimes we need specific functionality to handle duplicates and extract unique elements. In this article, I’ll show you how to extend the Array class with two custom methods: has_duplicated? to check if an array contains duplicates, and unique_elements to return only the unique elements from the array. These methods make working with arrays more intuitive and flexible.

The Code
Let’s start with the code that extends the Array class with our two methods.
# lib/array.rb
class Array
# Method to check if the array contains duplicated elements
def has_duplicated?
# If the array's size is different from the unique elements, there are duplicates
return false if self.size == self.uniq.size
true
end
# Method to get unique elements (those that appear only once in the array)
def unique_elements
self.tally.select { |k, v| v == 1 }.map do |element|
element.first
end
end
end

- has_duplicated?: This method checks whether an array contains any duplicate elements. It compares the size of the array to the size of the array after calling uniq, which removes duplicates. If the sizes differ, it returns true, indicating the presence of duplicates.
- unique_elements: This method leverages the tally method to count occurrences of each element in the array. It then selects elements that appear exactly once and returns them.
Do you need more hands for your Ruby on Rails project?

RSpec Tests

To ensure our methods work as expected, we can write some RSpec tests. Below is a test suite that checks both methods:
# spec/array_spec.rb
require "spec_helper"
require "array"
require "factories/students.rb"
RSpec.describe Array, "#arrays" do
let(:students) { build_list(:student, 20) }
before do
@arr = (students + students).shuffle
@last_names = @arr.map{ |stu| stu.last_name }
end
context "Return True if the array contains duplicated elements" do
it "should return true because the array contains duplicated elements" do
expect(@arr.has_duplicated?).to be_truthy
end
it "should return false because the array doesn't contain duplicated elements" do
expect(students.has_duplicated?).to be_falsey
end
it "should return true because last names are duplicated" do
expect(@last_names.has_duplicated?).to be_truthy
end
it "should return false because last names aren't duplicated" do
@last_names = students.map{ |stu| stu.last_name }
expect(@last_names.has_duplicated?).to be_falsey
end
end
context "Return unique elements from the array" do
it "Should return no elements when all elements are duplicated" do
expect(@arr.unique_elements).to be_empty
end
it "should return all elements because they are unique" do
expect(students.unique_elements).to match_array(students)
end
end
end

- Test Setup: The students array is created using a factory, and we duplicate the array to test for duplicates. We also extract the last names to verify the methods against real data.
- Test Cases:
has_duplicated? tests check whether duplicates are present in the array or not.
unique_elements tests verify that only elements that appear once are returned, or an empty array is returned if all elements are duplicated.
Factories for Test Data

In the tests, we use a Student factory to create test data. Here’s a basic factory definition for generating students with unique names and last names:
# spec/factories/students.rb
class Student
attr_accessor :name, :last_name
end
FactoryBot.define do
factory :student do
name { Faker::Name.unique.name }
last_name { Faker::Name.unique.last_name }
end
end

- FactoryBot: This gem helps generate test data, like students in our case. We use Faker to generate random names and last names for the students.
Usage Examples
Once you’ve added the methods to your project, you can use them like this:
# Example: Check if there are duplicated elements array = [1, 2, 3, 2, 4, 5] puts array.has_duplicated? # Output: true # Example: Get unique elements array = [1, 2, 2, 3, 3, 4] puts array.unique_elements # Output: [1, 4]

Conclusion
In this article, we enhanced Ruby’s Array class with two custom methods: has_duplicated? and unique_elements. These methods provide useful functionality for dealing with duplicates and extracting unique elements from arrays, improving readability and reducing the need for repetitive code. I hope this guide helps you extend Ruby arrays to suit your needs!
Feel free to adapt these methods to your own projects and share any feedback or improvements you might have.
