DEV Community

Cover image for How to make multidimensional / 2D Arrays & Hashes in Ruby ?
Ali Al Khawaja
Ali Al Khawaja

Posted on

How to make multidimensional / 2D Arrays & Hashes in Ruby ?

Arrays

A multidimensional array is a collection of data organized in multiple dimensions, such as a grid or table. It allows you to store and access data in a structured way, like rows and columns in a spreadsheet.

Nested Arrays (Multidimensional Arrays)

A nested array is an array where each element is itself an array. This creates a structure similar to rows and columns in a spreadsheet.

Accessing Elements

Elements in a nested array are accessed using multiple indices: array[row_index][column_index].

nestedArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
puts nestedArray[0][1] # Output: 2 (accesses the element at row 0, column 1)
puts nestedArray[2][2] # Output: 9 (accesses the element at row 2, column 2)
Enter fullscreen mode Exit fullscreen mode

You can also use negative indices to access elements from the end:

puts nestedArray[-1][-1] # Output: 9 (last row, last element)
Enter fullscreen mode Exit fullscreen mode

Handling Missing Rows or Columns

Attempting to access a non-existent row using array[row_index] will result in a NoMethodError because nil (the value for a missing row) doesn't respond to the [] method.

To avoid this, use the .dig(row_index, column_index) method. It safely returns nil if any part of the path is invalid, preventing errors:

nestedArray = [[1, 2], [3, 4]]
puts nestedArray.dig(2, 0) # Output: nil (row 2 doesn't exist)
puts nestedArray.dig(0, 5) # Output: nil (column 5 doesn't exist in row 0)
Enter fullscreen mode Exit fullscreen mode

Accessing a non-existent column in an existing row (e.g., nestedArray[0][5]) will return nil.

Creating Nested Arrays

When creating nested arrays, it's crucial to use a block with Array.new to avoid unintended sharing of inner arrays:

# Correct: Creates distinct inner arrays
nested_array = Array.new(3) { Array.new(2) }

# Incorrect: All inner arrays reference the same object
incorrect_nested = Array.new(3, Array.new(2)) # Avoid this!

incorrect_nested[0][0] = "changed"
puts incorrect_nested # Output: [["changed", nil], ["changed", nil], ["changed", nil]]
Enter fullscreen mode Exit fullscreen mode

The incorrect example demonstrates the issue of creating nested arrays without a block. All the inner arrays point to the same object in memory, meaning changing one changes them all.

Adding and Removing Elements

  • Adding: Use push to add elements to the end of a row: nested_array[row_index].push(value).
  • Removing: Use pop to remove the last element from a row: nested_array[row_index].pop.

Iterating Over Nested Arrays

Use nested each_with_index loops to iterate over rows and columns:

matrix = [[1, 2], [3, 4]]
matrix.each_with_index do |row, row_index|
  row.each_with_index do |element, col_index|
    puts "Element at [#{row_index}, #{col_index}]: #{element}"
  end
end
Enter fullscreen mode Exit fullscreen mode

Nested Hashes

Nested hashes are hashes where the values are themselves hashes. This is useful for representing structured data with key-value relationships within key-value relationships.

Accessing Data

Access data using chained keys: hash[:outer_key][:inner_key].

vehicles = {
  alice: { year: 2019, make: "Toyota", model: "Corolla" },
  bob: { year: 2022, make: "Tesla", model: "Model 3"}
}

puts vehicles[:alice][:model] # Output: Corolla
Enter fullscreen mode Exit fullscreen mode

Use dig to safely access nested values and avoid NoMethodError if a key is missing:

puts vehicles.dig(:charlie, :model) # Output: nil
Enter fullscreen mode Exit fullscreen mode

Adding and Removing Data

  • Adding: Assign a new hash to a key: hash[:new_key] = { key1: value1, key2: value2 }. Add to a nested hash: hash[:outer_key][:new_inner_key] = value.
  • Removing: Use delete to remove a key-value pair: hash.delete(:key) or hash[:outer_key].delete(:inner_key).

Important Methods for Collections (Arrays and Hashes)

  • select: Returns a new collection containing elements that satisfy a given condition.
  • collect (or map): Returns a new collection by transforming each element.
  • compact: Returns a new array with all nil elements removed.
  • filter_map: Combines filter (select) and map in one step.

You may notice that this guide is a bit weird , I tried something new , I took my note an told GeminiAI to rewrite it. and I already dislike it 😮‍💨

Top comments (0)