Contents

Collections

Ruby Arrays

An array is a collection of elements, which can be of the same or different types, stored in contiguous memory locations. The concept behind arrays is to group multiple elements together under a single variable name. In Ruby, arrays can store various types of objects like numbers, strings, hashes, symbols, or even other arrays. Arrays in Ruby are indexed, meaning each element is associated with an index number, starting from 0 for positive indices. Negative indices start from -1, representing elements from the end of the array.

Example of an Array:

				
					["Ruby", 42, 88.5, "Programming"]

				
			

In this example, the array contains four elements: a string ("Ruby"), an integer (42), a float (88.5), and another string ("Programming").

  • Positive indices start from 0.
  • Negative indices start from -1 and represent elements from the end of the array.

Ruby also supports multidimensional arrays (arrays within arrays), but here we will focus on one-dimensional arrays.

Creating a 1-D Array in Ruby

There are various ways to create an array in Ruby, but two of the most common methods are:

1. Using the new method: The new method can be used to create arrays by specifying its size and optional default values. The Array.new method can take zero, one, or more arguments.

Syntax:

				
					array_name = Array.new
				
			

Example:

				
					arr = Array.new
				
			

Here, arr is an empty array. To create an array with a specific size, pass a number to the new method.

Example:

				
					arr = Array.new(10) # Creates an array of size 10
puts arr.size       # Output: 10
puts arr.length     # Output: 10

				
			

You can also specify a default value for each element.

Example:

				
					arr = Array.new(3, "Hello")
puts "#{arr}"  # Output: ["Hello", "Hello", "Hello"]
				
			

Program Example:

				
					# Ruby program demonstrating array creation using the new method
arr1 = Array.new()         # Empty array
arr2 = Array.new(5)        # Array with 5 nil elements
arr3 = Array.new(4, "Hi")  # Array of size 4 with default element "Hi"

puts arr1.size             # Output: 0
puts arr2.length           # Output: 5
puts arr3.size             # Output: 4
puts "#{arr3}"             # Output: ["Hi", "Hi", "Hi", "Hi"]

				
			

2. Using the literal constructor []: The literal constructor [] can be used to quickly define an array with elements inside square brackets.

Example:

				
					arr = ['x', 'y', 'z', 'a', 'b']
puts "#{arr}"              # Output: ["x", "y", "z", "a", "b"]
puts "Size of array: #{arr.size}"   # Output: 5
				
			

3. Accessing Elements from an Array: In Ruby, you can access elements of an array using indices. The most common way is to use the element’s index number in square brackets []. If you try to access an element that doesn’t exist, Ruby will return nil.

Example:

				
					# Ruby program to demonstrate element access
arr = ["Hello", "World", "Ruby", "Array"]
puts arr[1]     # Output: World
puts arr[-1]    # Output: Array (last element)

				
			

4. Accessing Multiple Elements: To retrieve multiple elements from an array, pass two arguments to the [] method, specifying the starting index and the number of elements to retrieve.

Example:

				
					# Ruby program to demonstrate accessing multiple elements
arr = ["Hello", "World", "Ruby", "Array"]
puts arr[1, 2]  # Output: ["World", "Ruby"]

				
			

Ruby String

A string in Ruby is a sequence of characters that may include letters, numbers, or symbols. Ruby treats strings as objects, allowing them to be manipulated directly. Unlike some other languages, Ruby strings are mutable, meaning their content can be changed without creating new instances.

Creating Strings:

Strings in Ruby can be created by enclosing characters in either single or double quotes. You can also assign them to variables without specifying a type, as Ruby is dynamically typed.

Example:

				
					# Creating strings using single and double quotes

puts 'String created using single quotes'
puts "String created using double quotes"

# Storing strings in variables
str1 = "Hello"
str2 = 'World'

# Displaying stored strings
puts str1
puts str2

				
			

Output:

				
					String created using single quotes
String created using double quotes
Hello
World

				
			

Note: The main difference between using single and double quotes is that double quotes allow variable interpolation, while single quotes do not.

Example:

				
					# Difference between single and double quotes
name = "Ruby"

puts 'This is #{name}'   # No interpolation
puts "This is #{name}"   # Interpolation happens

				
			

Output:

				
					This is #{name}
This is Ruby
				
			
Strings as Objects:

Ruby is an object-oriented language, so strings are objects with associated data and methods.

Example:

				
					# Ruby strings as objects

str1 = "Programming"
str2 = String.new("Language")

puts str1  # Output: Programming
puts str2  # Output: Language

				
			
Accessing String Elements:

You can access individual characters or substrings in a string using square brackets []. The index of the character or range can be specified.

Example:

				
					# Accessing string elements

str = "Learning Ruby"

# Accessing substring using a string
puts str["Learning"]   # Output: Learning

# Accessing character using index
puts str[1]            # Output: e

# Accessing character using negative index
puts str[-1]           # Output: y

# Accessing substring using range of indices
puts str[9, 4]         # Output: Ruby

# Using range operators
puts str[9..12]        # Output: Ruby

				
			
Creating Multiline Strings:

Ruby offers multiple ways to create multiline strings, which can be achieved using double quotes, %/ /, or heredoc syntax.

Example:

				
					# Ruby program demonstrating multiline strings

# Using double quotes with newline characters
puts "This is a multiline string.\nIt spans multiple lines.\n"

# Using %/ /
puts %/This is another way to create a multiline string
which spans multiple lines./

# Using heredoc syntax
puts <<TEXT
This is created using heredoc syntax.
It also spans multiple lines.
TEXT

				
			
String Replication:

In Ruby, the * operator allows you to replicate strings multiple times.

Example:

				
					# Replicating strings

str = "Hello, Ruby!\n"

# Replicating the string 5 times
puts str * 5

				
			

Output:

				
					Hello, Ruby!
Hello, Ruby!
Hello, Ruby!
Hello, Ruby!
Hello, Ruby!

				
			

Ruby String Interpolation

String interpolation in Ruby allows combining strings in a dynamic way without needing to concatenate them using the + operator. It works only with double quotes ("") and provides a straightforward way to include variables or expressions within strings. When using interpolation, Ruby evaluates the variables or expressions inside #{} and replaces them with their values in the string.

Syntax:

				
					"#{variable}"
				
			

In the syntax above, everything inside the curly braces {} is an executable expression or variable.

Example 1:

				
					# Ruby program demonstrating string interpolation

x = 10
y = 25
puts "The number #{x} is less than #{y}"
				
			

Output:

				
					The number 10 is less than 25
				
			

In this example, the values of x and y are substituted directly into the string at the locations where the interpolation occurs.

Example 2:

				
					# Ruby program demonstrating string interpolation with variables

name = 'Rocket'
age = 5

# Using interpolation
puts "#{name} is #{age} years old"

# Concatenation without interpolation
puts name + " is " + age.to_s + " years old"

				
			

Output:

				
					Rocket is 5 years old
Rocket is 5 years old

				
			

In this example:

  • The first puts statement uses string interpolation, automatically converting the variables into a string format.
  • The second puts statement uses the + operator, requiring age to be converted to a string using to_s to avoid a type error.

Note: String interpolation is preferable because it’s cleaner, avoids explicit conversions, and can handle complex expressions inside the curly braces.

How String Interpolation Works:

When Ruby encounters #{} inside a string, it evaluates the expression or variable inside and inserts the resulting value into the string. This works for numbers, strings, or even more complex expressions.

For example:

				
					# Ruby program demonstrating interpolation of an expression

num = 20
puts "In five years, the number will be #{num + 5}"

				
			

Output:

				
					In five years, the number will be 25
				
			

Ruby Hashes Basics

A hash in Ruby is a data structure that holds a collection of unique keys, each associated with a corresponding value. Hashes are also called associative arrays or maps because they map keys to values. Unlike arrays, which are indexed by integers, hashes can be indexed by objects (such as strings or symbols).

Creating Hashes

There are several ways to create a hash in Ruby:

1. Using the new Method: The new method creates an empty hash with no default value unless specified.

Syntax:

				
					hash_variable = Hash.new
				
			

Example:

				
					my_hash = Hash.new

				
			

This will create an empty hash called my_hash. You can also specify a default value for the hash, which will be returned when trying to access a key that does not exist.

				
					my_hash = Hash.new("default_value")
				
			

Now, if a key is not found in my_hash, it will return "default_value".

2. Using {} Braces: This is the most common way to create a hash, using curly braces {} to define key-value pairs.

Syntax:

				
					hash_variable = { "key1" => value1, "key2" => value2 }
				
			

Example:

				
					languages = { "Ruby" => 1, "Python" => 2 }
				
			

This hash associates "Ruby" with 1 and "Python" with 2.

Fetching Hash Values

To retrieve a value from a hash, use square brackets [] and pass the key as an argument.

Example:

				
					# Define a hash with some key-value pairs
student_scores = {
  "Alice" => 85,
  "Bob" => 92,
  "Charlie" => 78
}

# Fetch values using their keys
puts student_scores["Alice"]   # Output the score of Alice
puts student_scores["Bob"]     # Output the score of Bob
puts student_scores["Charlie"] # Output the score of Charlie

				
			

Output:

				
					85
92
78

				
			

2. Numbers

Ruby supports different types of numbers, including integers and floating-point numbers. You can write numbers of any size, using underscores (_) for readability. Ruby allows various numerical formats, including decimal, hexadecimal, octal, and binary.

Example:

				
					# Ruby program to demonstrate hash creation and fetching values

my_hash = { "Apple" => 3, "Banana" => 5 }

# Fetching values using keys
puts my_hash["Apple"]    # Output: 3
puts my_hash["Banana"]   # Output: 5

				
			
Modifying Hashes in Ruby

You can modify a hash by adding, removing, or changing key-value pairs. Modifying the value of an existing key is done by reassigning the value.

Example:

				
					# Ruby program to demonstrate modifying a hash

fruits = { "Apple" => 3, "Banana" => 5 }

puts "Before Modification:"
puts fruits["Apple"]    # Output: 3
puts fruits["Banana"]   # Output: 5

# Modifying the values
fruits["Apple"] = 10
fruits["Banana"] = 8

puts "\nAfter Modification:"
puts fruits["Apple"]    # Output: 10
puts fruits["Banana"]   # Output: 8

				
			
Overwriting Key Values

If you assign multiple values to the same key in a hash, the last assignment overwrites the previous ones. This does not raise an error but may give a warning.

Example:

				
					# Ruby program to demonstrate overwriting keys

my_hash = { "Apple" => 3, "Apple" => 7, "Banana" => 5 }

puts "Before Modifying:"
puts my_hash["Apple"]    # Output: 7 (last assigned value)
puts my_hash["Banana"]   # Output: 5

# Modifying the hash
my_hash["Apple"] = 12
my_hash["Banana"] = 10

puts "\nAfter Modifying:"
puts my_hash["Apple"]    # Output: 12
puts my_hash["Banana"]   # Output: 10

				
			

Ruby Hash Class

In Ruby, a Hash is a collection of unique keys and their associated values. Unlike arrays, hashes allow indexing with arbitrary object types as keys. Iterating through a hash may return key-value pairs in an arbitrary order, not necessarily in the insertion order. By default, hashes return nil when trying to access keys that do not exist.

Class Methods

1. []: Creates a new hash populated with the given key-value pairs.

				
					# Example:
p Hash["a", 1, "b", 2] 
p Hash["a" => 1, "b" => 2]

				
			

Output:

				
					{"a"=>1, "b"=>2}
{"a"=>1, "b"=>2}

				
			

2. new: Returns an empty hash. If a key that doesn’t exist is accessed, the return value depends on the form of new. By default, nil is returned, but a custom object or block can be specified for default values.

				
					# Example:
h = Hash.new("default_value")
p h["key1"] = 10
p h["key2"] = 20
p h["key3"]       # key3 doesn't exist, returns default

				
			

Output:

				
					10
20
"default_value"
				
			
3. try_convert: Converts an object into a hash, if possible, and returns the hash or nil if conversion fails.
				
					# Example:
p Hash.try_convert({1 => 2})
p Hash.try_convert("1 => 2")  # Not a hash

				
			

Output:

				
					{1=>2}
nil

				
			
Instance Methods

1. ==: Checks if two hashes are equal, meaning both contain the same keys and corresponding values.

				
					# Example:
h1 = {"a" => 1, "b" => 2}
h2 = {"b" => 2, "a" => 1}
h3 = {"a" => 3, "b" => 2}
p h1 == h2  # true
p h1 == h3  # false

				
			
2. [] (Element Reference): Retrieves the value associated with the specified key, or returns nil if the key is not found.
				
					# Example:
h = {"a" => 10, "b" => 20}
p h["a"]  # 10
p h["c"]  # nil

				
			
3. []= (Element Assignment): Assigns a value to a key in the hash.
				
					# Example:
h = {"a" => 10, "b" => 20}
h["a"] = 50
h["c"] = 30
p h  # {"a"=>50, "b"=>20, "c"=>30}

				
			
4. clear: Removes all key-value pairs from the hash.
				
					# Example:
h = {"a" => 10, "b" => 20}
h.clear
p h  # {}
				
			
5. default: Returns the default value for missing keys.
				
					# Example:
h = Hash.new("default_value")
p h.default  # "default_value"
				
			
6. delete: Deletes a key-value pair from the hash by key, returning the value or nil if the key is not found.
				
					# Example:
h = {"a" => 10, "b" => 20}
p h.delete("a")  # 10
p h.delete("z")  # nil

				
			
7. each: Iterates over each key-value pair in the hash.
				
					# Example:
h = {"a" => 10, "b" => 20}
h.each { |key, value| puts "#{key}: #{value}" }

				
			

Output:

				
					a: 10
b: 20

				
			

8. has_key?: Returns true if the specified key is present in the hash, otherwise false.

				
					# Example:
h = {"a" => 10, "b" => 20}
p h.has_key?("a")  # true
p h.has_key?("z")  # false

				
			

9. invert: Swaps keys and values, returning a new hash.

				
					# Example:
h = {"a" => 1, "b" => 2}
p h.invert  # {1 => "a", 2 => "b"}

				
			
10. merge: Combines two hashes, giving precedence to the second hash’s values for duplicate keys.
				
					# Example:
h1 = {"a" => 1, "b" => 2}
h2 = {"b" => 3, "c" => 4}
p h1.merge(h2)  # {"a" => 1, "b" => 3, "c" => 4}

				
			
11. reject: Returns a new hash with key-value pairs removed where the block evaluates to true.
				
					# Example:
h = {"a" => 1, "b" => 2, "c" => 3}
p h.reject { |k, v| v > 1 }  # {"a" => 1}