rubyguides

Array#join

arr.join(separator=nil) -> string

.join converts an array elements into a single string by concatenating their string representations with a separator between each element. This is the inverse operation of String#split, and it is one of the most common ways to build output strings from collections.

Use join when the array already contains the pieces you want to print, store, or send over a boundary. The separator controls how readable the result is: an empty separator builds one continuous string, while commas, newlines, and spaces make the result easier for people or parsers to read.

Syntax

array.join           # join with empty string (default)
array.join("")      # join with empty string explicitly  
array.join(",")     # join with comma
array.join("\n")    # join with newline
array.join(", ")    # join with comma and space

Parameters

ParameterTypeDefaultDescription
separatorString or nilnilThe string to insert between each element. If nil, uses the global $, variable (which defaults to nil, producing an empty string).

Examples

Basic usage

fruits = ["apple", "banana", "cherry"]

fruits.join
# => "applebananacherry"

fruits.join(", ")
# => "apple, banana, cherry"

fruits.join(" | ")
# => "apple | banana | cherry"

Without a separator argument, .join produces a concatenated string with no delimiter between elements. That default is convenient for quick concatenation, but in practice most readable output needs a separator. The pipe delimiter in the third example shows how a separator can turn an array into a display string that is easy to scan without extra formatting steps.

Working with numbers

numbers = [1, 2, 3, 4, 5]

numbers.join("-")
# => "1-2-3-4-5"

# Numbers are converted to strings automatically
[10, 20, 30].join(", ")
# => "10, 20, 30"

.join automatically converts non-string elements using to_s, so you can work with arrays containing mixed types.

That automatic conversion is convenient, but it also means the result depends on each element’s to_s implementation. For user-facing output, map values into the exact text you want before calling join so the final string stays predictable.

Nested arrays

nested = ["a", ["b", ["c", "d"]], "e"]

nested.join
# => "abcde"

nested.join(", ")
# => "a, b, c, d, e"

.join handles nested arrays recursively. It calls .join on any array element, so deeply nested arrays flatten automatically into the output string.

Recursive joining is useful for compact output, but it can surprise readers who expect nested arrays to stay visible. If the nested structure matters, format each row yourself before joining the rows together.

Building CSV-like output

rows = [
  ["Name", "Age", "City"],
  ["Alice", "30", "NYC"],
  ["Bob", "25", "LA"]
]

rows.map { |row| row.join(",") }.join("\n")
# => Name,Age,City
# => Alice,30,NYC
# => Bob,25,LA

This pattern is useful for generating CSV data from arrays of arrays.

For real CSV files, prefer Ruby’s CSV library so quoting and embedded commas are handled correctly. The join version is best for simple output where you control the values and know they do not need escaping.

Common Patterns

Joining with newlines for display

items = ["Item 1", "Item 2", "Item 3"]

puts items.join("\n")
# Output:
# Item 1
# Item 2
# Item 3

Joining with newlines is a common shortcut for displaying lists in the terminal without building a loop. Each element appears on its own line, and the output is ready to pass to puts or write to a file. This pattern works well for logs, reports, and any text where each item should stand on its own line.

Creating URL query strings

params = ["page=1", "limit=10", "sort=name"]

"?" + params.join("&")
# => "?page=1&limit=10&sort=name"

Building query strings with join is a lightweight alternative to URI encoding libraries when the keys and values are already under your control. The ampersand separator mirrors what browsers and HTTP clients expect, and the leading question mark completes the query string format in a single expression.

Flattening and joining in one step

matrix = [[1, 2], [3, 4], [5, 6]]

matrix.flatten.join(",")
# => "1,2,3,4,5,6"

This is equivalent to .join on nested arrays since .join already handles recursion. The explicit flatten call can still be helpful when you want to show the shape change before building the string. It makes the transformation easier to read in code review, especially when the nested structure was built by earlier steps in a pipeline.

The explicit flatten call can still be helpful when you want to show the shape change before building the string. It makes the transformation easier to read in code review, especially when the nested structure was built by earlier steps in a pipeline. The two-step approach also makes it easy to add intermediate transformations before the final join.

Using with map for custom formatting

users = [{name: "Alice", age: 30}, {name: "Bob", age: 25}]

users.map { |u| "\#{u[:name]} (\#{u[:age]})" }.join(", ")
# => "Alice (30), Bob (25)"

The map-and-join combination is one of the most flexible patterns for building display strings. It separates the formatting logic from the concatenation, so each step stays small and testable on its own. Once you have a clean array of formatted strings, join handles the final assembly with whatever separator makes sense for the output format.

Errors

.join is forgiving - it works with arrays of any types and handles nil elements gracefully:

[nil, "a", nil, "b"].join(",")
# => ",a,,b"

Nil elements produce empty strings in the output. That behavior is useful for loose display strings, but it can hide missing data. If blanks would be confusing, replace nil values with a marker before joining so the final output shows the absence clearly. A quick map before join gives you full control over how each element appears in the finished string.

That behavior is useful for loose display strings, but it can hide missing data. If blanks would be confusing, replace nil values with a marker before joining so the final output shows the absence clearly.

See Also

  • String#split — The inverse of join; splits a string into an array
  • Array#flatten — Flattens nested arrays before joining