Question

Check Whether a Value Is an Array in Ruby and Count Items

rubysyntax

Question

What is the correct Ruby way to determine whether a value is an array?

For example, I want a string to be treated as not being an array and an array to be recognized as one:

is_array("something") # => false
is_array(["something", "else"]) # => true

How can I also get the number of items when the value is an array?

Short Answer

You will learn how Ruby identifies arrays, how to check a value safely with is_a?(Array), and how to count array elements using length, size, or count.

Concept

Ruby values are objects, and every object has a class. An array such as ["something", "else"] is an instance of Array, while "something" is an instance of String.

Use is_a?(Array) to ask whether an object is an array:

"something".is_a?(Array)             # => false
["something", "else"].is_a?(Array)  # => true

Once you know you have an array, use length or size to get its number of elements:

items = ["something", "else"]
items.length # => 2
items.size   # => 2

Checking a value's type matters when input may come from JSON, APIs, forms, configuration files, or method arguments. It helps your program avoid calling array-only methods on a string, number, or nil.

Mental Model

Think of an Array as a labelled container with several slots.

  • is_a?(Array) checks the label on the container: “Is this an Array?”
  • length counts how many slots currently contain elements.

A string is not an array container, even though it can contain multiple characters. Therefore, a string fails the array check and should not be handled as a list of items unless you deliberately convert it.

Take Quiz

Syntax and Examples

Use is_a?(Array) for a normal Ruby type check.

value = ["red", "green", "blue"]

if value.is_a?(Array)
  puts "This is an array with #{value.length} items."
else
  puts "This is not an array."
end

Output:

This is an array with 3 items.

You can also write the type check with Array === value:

Array === [1, 2]  # => true
Array === "text" # => false

However, value.is_a?(Array) is usually easier for beginners to read.

To count elements in an array:

numbers = [10, 20, 30]

numbers.length # => 3
numbers.size   # => 3
numbers.count  # => 3

For an array with no elements, all three return 0:

[].length # => 0

Step by Step Execution

Consider this method that accepts either an array or another kind of value:

def describe_items(value)
  return "Not an array" unless value.is_a?(Array)

  "Array contains #{value.length} item(s)"
end

puts describe_items("something")
puts describe_items(["something", "else"])

Step by step:

  1. describe_items("something") receives a String.
  2. value.is_a?(Array) is false.
  3. The unless condition returns early with "Not an array".
  4. describe_items(["something", "else"]) receives an Array.
  5. The type check is true, so execution continues.
  6. value.length counts the two elements.
  7. The method returns "Array contains 2 item(s)".

Output:

Not an array
Array contains 2 item(s)

Real World Use Cases

  • JSON API responses: Confirm that a field such as tags is an array before iterating over it.
  • Form parameters: Handle a field that may arrive as one value or as a list of selected values.
  • Configuration: Validate that a setting like allowed_hosts contains a list.
  • Data imports: Check a CSV or parsed data value before treating it as a collection.
  • Method inputs: Give a clear error when a method requires a list of records or IDs.

Example API-style validation:

def process_tags(tags)
  return [] unless tags.is_a?(Array)

  tags.map { |tag| tag.to_s.downcase }
end

process_tags(["Ruby", "Web"]) # => ["ruby", "web"]
process_tags("Ruby")            # => []
Take Quiz

Real Codebase Usage

In production Ruby code, type checks are commonly paired with validation and guard clauses.

A guard clause handles invalid input immediately, keeping the main code path simple:

def total_price(prices)
  raise ArgumentError, "prices must be an Array" unless prices.is_a?(Array)

  prices.sum
end

When an array is optional, a default may be more appropriate:

def send_notifications(recipients)
  recipients = [] unless recipients.is_a?(Array)

  recipients.each do |recipient|
    puts "Sending notification to #{recipient}"
  end
end

Developers often use array methods after validation:

users = [{ active: true }, { active: false }, { active: true }]
active_users = users.select { |user| user[:active] }

active_users.count # => 2

If a method's contract clearly says it receives an array, repeated type checks inside that method may be unnecessary. Validate at the boundary where external input enters the application.

Common Mistakes

Calling length on a value before checking it

A string has a length too, but it means character count rather than item count:

value = "hello"
value.length # => 5, not an array item count

Check for an array first when array semantics matter.

value.length if value.is_a?(Array)

Calling array methods on nil

This raises an error:

value = nil
value.length
# NoMethodError

Use a guard clause or a default:

items = value.is_a?(Array) ? value : []
items.length # => 0

Using instance_of?(Array) when subclasses should count

value.instance_of?(Array)

instance_of? is stricter: it only returns true when the object's direct class is exactly Array. Usually, is_a?(Array) is the better choice because it also supports subclasses.

Confusing count with length

Without arguments, count returns the number of elements. With an argument or block, it counts matching elements:

[1, 2, 2, 3].count      # => 4
[1, 2, 2, 3].count(2)   # => 2
[1, 2, 2, 3].count(&:even?) # => 2

Use length or size when you simply need the total number of elements.

Comparisons

TaskRecommended Ruby codeNotes
Check whether a value is an arrayvalue.is_a?(Array)Clear and commonly used.
Check with case-equalityArray === valueWorks, but is less conversational to read.
Require the exact direct classvalue.instance_of?(Array)Usually too strict.
Get total elementsarray.length or array.sizeEquivalent for arrays.
Count total elementsarray.countSame result with no argument or block.
Count matching elementsarray.count(item) or array.count { ... }Useful for filtering counts.

length and size are interchangeable for Ruby arrays. Many developers use length when emphasizing a count and size when discussing a collection's size; both are valid.

Take Quiz

Cheat Sheet

# Type check
value.is_a?(Array)

"text".is_a?(Array) # => false
[1, 2].is_a?(Array)  # => true

# Total number of array elements
array.length
array.size
array.count

["a", "b"].length # => 2
[].size              # => 0

# Count matching elements
[1, 2, 2, 3].count(2)          # => 2
[1, 2, 2, 3].count(&:even?)    # => 2

# Safe fallback when input might not be an array
items = value.is_a?(Array) ? value : []
  • Prefer is_a?(Array) for ordinary array checks.
  • Prefer length or size for the total item count.
  • count can also count only elements that match a value or condition.
  • Do not assume nil, strings, hashes, and arrays support the same methods.

FAQ

How do I check if something is an array in Ruby?

Use value.is_a?(Array). It returns true for arrays and false for values such as strings, integers, hashes, and nil.

What is the difference between length, size, and count for an array?

With no arguments, all return the number of elements. count is additionally useful with an argument or block to count only matching elements.

Does a Ruby string count as an array?

No. A string is a String object, not an Array, even though it contains characters.

What happens when I call length on an empty array?

It returns 0.

Should I use is_a?(Array) or instance_of?(Array)?

Usually use is_a?(Array). It is more flexible because it accepts instances of Array subclasses too.

How can I safely treat a non-array as an empty array?

Use a conditional fallback:

items = value.is_a?(Array) ? value : []

Can I count only particular values in an array?

Yes. Use count with a value or block:

["a", "b", "a"].count("a") # => 2
Take Quiz

Mini Project

Description

Build a small input inspector for a command-line Ruby script. It receives a value, reports whether it is an array, and, when appropriate, reports the total item count. This mirrors validation performed before processing input from an API or configuration file.

Goal

Create a method that safely describes arrays and rejects non-array values.

Requirements

  • Create a method named array_report that accepts one value.
  • Return a message when the value is not an array.
  • Return the number of elements when the value is an array.
  • Test the method with a string, an empty array, and an array with multiple values.
  • Use is_a?(Array) for the type check.
Take Quiz

Keep learning

Related questions

View more