ESC
Type to search...
S
Soli Docs

Arrays

Ordered, mutable collections with powerful built-in methods for transformation and manipulation.

Creating Arrays

Array Literals

Create arrays using square brackets with comma-separated values.

# Basic array literal
let numbers = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob", "Charlie"]
let mixed = [1, "hello", true, null]

# Empty array
let empty = []

# Nested arrays
let matrix = [[1, 2], [3, 4], [5, 6]];
Type Annotations

Optionally specify array types for clarity and type safety.

# Typed arrays
let scores: Int[] = [95, 87, 92, 88, 90]
let names: String[] = ["Alice", "Bob", "Charlie"]
let flags: Bool[] = [true, false, true]

# Multi-dimensional arrays
let matrix: Int[][] = [[1, 2], [3, 4], [5, 6]];
range(start, end, step?)

Creates an array of numbers from start to end (exclusive).

range(0, 5)        # [0, 1, 2, 3, 4]
range(1, 10)       # [1, 2, 3, 4, 5, 6, 7, 8, 9]
range(0, 10, 2)    # [0, 2, 4, 6, 8] (step of 2)
range(5, 0, -1)    # [5, 4, 3, 2, 1] (reverse)

Accessing Elements

Index Access

Access elements using zero-based indexing. Negative indices count from the end.

let arr = [10, 20, 30, 40, 50]

# Zero-based indexing
print(arr[0]);    # 10 (first element)
print(arr[2]);    # 30 (third element)

# Negative indexing
print(arr[-1]);   # 50 (last element)
print(arr[-2]);   # 40 (second to last)

# Out of bounds returns null
print(arr[10]);   # null
Modifying Elements

Arrays are mutable - you can modify elements by index.

let arr = [1, 2, 3, 4, 5]

# Modify existing element
arr[0] = 100
print(arr);  # [100, 2, 3, 4, 5]

# Add new element (extends array)
arr[10] = 999
print(arr);  # [100, 2, 3, 4, 5, null, null, null, null, null, 999]

Array Methods

.map(def)

Transform each element using a function. Returns a new array.

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

# Double each number
let doubled = numbers.map(|x| x * 2)
print(doubled);  # [2, 4, 6, 8, 10]

# Trailing block syntax (equivalent)
let doubled = numbers.map |x| x * 2 end

# Convert to strings
let strings = numbers.map(|x| str(x))
print(strings);  # ["1", "2", "3", "4", "5"]
.filter(def)

Keep elements matching a condition. Returns a new array.

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Keep only even numbers
let evens = numbers.filter(|x| x % 2 == 0)
print(evens);  # [2, 4, 6, 8, 10]

# Trailing block syntax (equivalent)
let evens = numbers.filter |x| x % 2 == 0 end

# Keep numbers greater than 5
let large = numbers.filter(|x| x > 5)
print(large);  # [6, 7, 8, 9, 10]
.reduce(def, initial)

Accumulate array elements to a single value.

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

# Sum all numbers
let sum = numbers.reduce(|acc, x| acc + x, 0)
print(sum);  # 15

# Trailing block syntax — extra args in parens, block after
let sum = numbers.reduce(0) |acc, x| acc + x end

# Product of all numbers
let product = numbers.reduce(|acc, x| acc * x, 1)
print(product);  # 120
.each(def)

Iterate over elements for side effects. Returns the original array.

let numbers = [1, 2, 3]

# Print each number
numbers.each(|x| print(x))
# Output: 1
#         2
#         3

# Trailing block syntax (equivalent)
numbers.each |x| print(x) end

# Modify external state
let sum = 0;
numbers.each |x| sum = sum + x end
print(sum);  # 6
.find(def) / .any?(def) / .all?(def)

Search and check array elements.

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

# find - returns first matching element
let first_even = numbers.find(|x| x % 2 == 0)
print(first_even)  # 2

# any? - returns true if any element matches
let has_large = numbers.any?(|x| x > 4)
print(has_large)  # true

# all? - returns true if all elements match
let all_positive = numbers.all?(|x| x > 0)
print(all_positive)  # true

# Trailing block syntax works too
let found = numbers.find |x| x > 3 end
let any = numbers.any? |x| x > 4 end
let all = numbers.all? |x| x > 0 end
.sort / .sort(def)

Sort elements. Default is ascending order, or provide a custom comparator.

let numbers = [3, 1, 4, 1, 5, 9, 2, 6]

# Default sort (ascending)
let sorted = numbers.sort
print(sorted);  # [1, 1, 2, 3, 4, 5, 6, 9]

# Custom comparator (descending)
let desc = numbers.sort(|a, b| b - a)
print(desc);  # [9, 6, 5, 4, 3, 2, 1, 1]

# Trailing block syntax
let desc = numbers.sort |a, b| b - a end

# Sort by string length
let words = ["cherry", "pie", "apple"]
let by_length = words.sort |a, b| len(a) - len(b) end
print(by_length);  # ["pie", "apple", "cherry"]
.sort_by(key) / .sort_by(def)

Sort an array of hashes by a key, or use a function to extract the sort value from each element.

let people = [
  { "name": "Charlie", "age": 30 },
  { "name": "Alice", "age": 25 },
  { "name": "Bob", "age": 20 }
]

# Sort by hash key (string argument)
let by_name = people.sort_by("name")
print(by_name.map(|p| p.get("name")));  # [Alice, Bob, Charlie]

let by_age = people.sort_by("age")
print(by_age.map(|p| p.get("age")));  # [20, 25, 30]

# Sort by function (for computed values)
let words = ["cherry", "pie", "apple"]
let by_length = words.sort_by(|w| len(w))
print(by_length);  # [pie, apple, cherry]
.reverse

Return a new array with elements in reverse order.

let arr = [1, 2, 3, 4, 5]
let reversed = arr.reverse
print(reversed);  # [5, 4, 3, 2, 1]
print(arr);       # [1, 2, 3, 4, 5] (original unchanged)
.uniq

Remove duplicate elements. Returns a new array with unique values.

let arr = [1, 2, 2, 3, 3, 3, 4]
let unique = arr.uniq
print(unique)  # [1, 2, 3, 4]
.compact

Remove null values from the array.

let arr = [1, null, 2, null, 3, null]
let cleaned = arr.compact
print(cleaned)  # [1, 2, 3]
.flatten / .flatten(n)

Flatten nested arrays. Optionally specify depth.

let nested = [[1, 2], [3, 4], [5, 6]]
let flat = nested.flatten
print(flat);  # [1, 2, 3, 4, 5, 6]

# Flatten only 1 level deep
let deep = [[1, 2], [[3, 4]]]
let partial = deep.flatten(1)
print(partial);  # [1, 2, [3, 4]]
.first / .last

Get the first or last element.

let arr = [10, 20, 30, 40, 50]
print(arr.first);  # 10
print(arr.last);   # 50

# Returns null for empty arrays
let empty = []
print(empty.first);  # null
print(empty.last);   # null
.empty?() / .blank?() / .present?() / .includes?(value) / .contains(value)

Check if array is empty, blank, present, or contains a value. .includes? and .contains are aliases.

let arr = [1, 2, 3]

print(arr.empty?);         # false
print(arr.blank?);         # false
print(arr.present?);       # true
print(arr.includes?(2));   # true
print(arr.contains(2));    # true

let empty = []
print(empty.empty?);       # true
print(empty.blank?);       # true
print(empty.present?);     # false
.sample / .shuffle

Random element selection and shuffling.

let arr = [1, 2, 3, 4, 5]

# Get random element
let random = arr.sample
print(random);  # Random element (e.g., 3)

# Shuffle array
let shuffled = arr.shuffle
print(shuffled);  # Randomized order (e.g., [3, 1, 5, 2, 4])
.take(n) / .drop(n)

Take or skip the first n elements.

let arr = [1, 2, 3, 4, 5]

# Take first n elements
let first_three = arr.take(3)
print(first_three);  # [1, 2, 3]

# Skip first n elements
let rest = arr.drop(3)
print(rest);  # [4, 5]
.zip(other)

Combine two arrays into pairs.

let names = ["Alice", "Bob", "Charlie"]
let scores = [95, 87, 92]

let pairs = names.zip(scores)
# [["Alice", 95], ["Bob", 87], ["Charlie", 92]]
.sum / .min / .max

Numeric aggregation methods.

let numbers = [10, 5, 8, 3, 12]

print(numbers.sum);   # 38.0
print(numbers.min);   # 3
print(numbers.max);   # 12
.join(delimiter)

Joins array elements into a string using the specified delimiter.

let words = ["Hello", "World"]
print(words.join(" "));   # "Hello World"

let numbers = [1, 2, 3, 4, 5]
print(numbers.join("-")); # "1-2-3-4-5"

let paths = ["usr", "local", "bin"]
print(paths.join("/"));   # "usr/local/bin"

Method Chaining

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Chain multiple methods together
let result = numbers
    .filter(|x| x % 2 == 0)   # Keep evens: [2, 4, 6, 8, 10]
    .map(|x| x * x)           # Square them: [4, 16, 36, 64, 100]
    .filter(|x| x < 50)       # Keep less than 50: [4, 16, 36]

print(result);  # [4, 16, 36]

# With pipeline operator
let result2 = numbers
    |> filter(|x| x > 5)
    |> map(|x| x * 2)
    |> sum
print(result2);  # 90

Array Class Methods

Array literals are automatically wrapped in an Array class instance that provides methods for manipulation and transformation. Each array value has access to these methods via dot notation.

to_string()

Returns a formatted string representation of the array. Called automatically in REPL.

let arr = [1, 2, 3]
# In REPL, displays: [1, 2, 3]
# Equivalent to: arr.to_string()
to_json

Serializes the array to a JSON string.

let arr = [1, "hello", true, null]
arr.to_json  # '[1,"hello",true,null]'

let nested = [{name: "Alice"}, {name: "Bob"}]
nested.to_json  # '[{"name":"Alice"},{"name":"Bob"}]'
.length / .len / .size

Returns the number of elements in the array.

let arr = [1, 2, 3]
arr.length  # 3
arr.len     # 3
arr.size    # 3
push(value) / pop()

Adds an element to the end or removes and returns the last element.

let arr = []
arr.push(1)  # [1]
arr.push(2)  # [1, 2]
let last = arr.pop  # 2, arr is now [1]
get(index)

Returns the element at the specified index. Supports negative indices for backward access.

let arr = ["first", "second", "third"]
arr.get(0);      # "first"
arr.get(2);      # "third"
arr.get(-1);     # "third" (last)
arr.get(-2);     # "second"
clear()

Removes all elements from the array.

let arr = [1, 2, 3]
arr.clear
arr.length  # 0
.class / .inspect / .nil? / .is_a?

Type introspection methods available on all types.

let arr = [1, 2, 3]
arr.class         # "array"
arr.inspect       # "[1, 2, 3]"
arr.nil?          # false
arr.is_a?("array")  # true