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
numbers = [1, 2, 3, 4, 5]
names = ["Alice", "Bob", "Charlie"]
mixed = [1, "hello", true, null]
# Empty array
empty = []
# Nested arrays
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)
%w[] / %i[] / %n[]
Shorthand syntax for creating arrays of strings (%w), symbols (%i), or numbers (%n). Elements are separated by whitespace. Use D suffix for decimals.
# %w[] creates string arrays
words = %w[foo bar baz]
print(words); # ["foo", "bar", "baz"]
# %i[] creates symbol arrays
methods = %i[get post put delete]
print(methods); # [:get, :post, :put, :delete]
# %n[] creates number arrays (integers, floats, and decimals with D suffix)
nums = %n[1 2.5 3.5D]
print(nums); # [1, 2.5, 3.5]
# Empty arrays
%w[] # []
%i[] # []
%n[] # []
# Multiline for readability
const HTTP_METHODS = %i[
get
post
put
delete
patch
]
# Number arrays for coordinates
const BOX = %n[0 0 100 100]
# Equivalent to regular arrays
%w[a b c] == ["a", "b", "c"]
%i[a b c] == [:a, :b, :c]
%n[1 2 3] == [1, 2, 3]
%n[1.5D 2.5D] == [1.5D, 2.5D]
Accessing Elements
Index Access
Access elements using zero-based indexing. Negative indices count from the end.
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.
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 Operators
-
Subtract an array from another array, removing all matching elements. Returns a new array (original unchanged). Uses identity comparison for instances.
# Basic array subtraction
a = [1, 2, 3]
b = [1]
result = a - b
print(result); # [2, 3]
# Remove multiple occurrences
a = [1, 2, 1, 3, 1]
b = [1]
result = a - b
print(result); # [2, 3]
# Works with strings
fruits = ["apple", "banana", "cherry"]
to_remove = ["banana"]
print(fruits - to_remove); # ["apple", "cherry"]
# Instance comparison uses identity (pointer equality)
class Person {
name: String;
def new(n) { this.name = n; }
}
p1 = Person.new({"name": "Alice"})
p2 = Person.new({"name": "Bob"})
arr = [p1, p2]
result = arr - [p1]
print(result); # []
+
Concatenate two arrays, returning a new array containing all elements from both. Original arrays are unchanged.
# Concatenate two arrays
a = [1, 2]
b = [3, 4]
result = a + b
print(result); # [1, 2, 3, 4]
# Works with any types
nums = [1, 2] + [3, 4]
strings = ["a", "b"] + ["c", "d"]
# Original arrays unchanged
x = [1, 2]
y = [3, 4]
combined = x + y
print(x); # [1, 2]
print(y); # [3, 4]
Array Methods
.map(def)
Transform each element using a function. Returns a new array.
numbers = [1, 2, 3, 4, 5]
# Double each number
doubled = numbers.map(|x| x * 2)
print(doubled); # [2, 4, 6, 8, 10]
# Trailing block syntax (equivalent)
doubled = numbers.map |x| x * 2 end
# Symbol shorthand: &:method → |__it| __it.method()
strings = numbers.map(&:to_s)
print(strings); # ["1", "2", "3", "4", "5"]
# Convert to strings
strings = numbers.map(|x| str(x))
print(strings); # ["1", "2", "3", "4", "5"]
.filter(def)
Keep elements matching a condition. Returns a new array.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Keep only even numbers
evens = numbers.filter(|x| x % 2 == 0)
print(evens); # [2, 4, 6, 8, 10]
# Trailing block syntax (equivalent)
evens = numbers.filter |x| x % 2 == 0 end
# Symbol shorthand: &:predicate → |__it| __it.predicate()
evens = numbers.filter(&:even?)
print(evens); # [2, 4, 6, 8, 10]
# Keep numbers greater than 5
large = numbers.filter(|x| x > 5)
print(large); # [6, 7, 8, 9, 10]
.reduce(def, initial)
Accumulate array elements to a single value.
numbers = [1, 2, 3, 4, 5]
# Sum all numbers
sum = numbers.reduce(|acc, x| acc + x, 0)
print(sum); # 15
# Trailing block syntax — extra args in parens, block after
sum = numbers.reduce(0) |acc, x| acc + x end
# Product of all numbers
product = numbers.reduce(|acc, x| acc * x, 1)
print(product); # 120
.each(def)
Iterate over elements for side effects. Returns the original array.
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
sum = 0;
numbers.each |x| sum = sum + x end
print(sum); # 6
.each_with_index(def)
Iterate over elements with their index. The block receives (value, index). Returns the original array.
names = ["Alice", "Bob", "Charlie"]
names.each_with_index(|name, i| print("#{i}: #{name}"))
# Output: 0: Alice
# 1: Bob
# 2: Charlie
# Trailing block syntax (equivalent)
names.each_with_index |name, i| print("#{i}: #{name}") end
.find(def) / .any?(def) / .all?(def)
Search and check array elements.
numbers = [1, 2, 3, 4, 5]
# find - returns first matching element
first_even = numbers.find(|x| x % 2 == 0)
print(first_even) # 2
# any? - returns true if any element matches
has_large = numbers.any?(|x| x > 4)
print(has_large) # true
# all? - returns true if all elements match
all_positive = numbers.all?(|x| x > 0)
print(all_positive) # true
# Trailing block syntax works too
found = numbers.find |x| x > 3 end
any = numbers.any? |x| x > 4 end
all = numbers.all? |x| x > 0 end
.index_of(value)
Return the position of the first element equal to value, or -1 if not found.
names = ["Alice", "Bob", "Charlie", "Bob"]
print(names.index_of("Bob")); # 1 (first match)
print(names.index_of("Charlie")); # 2
print(names.index_of("Dave")); # -1 (not found)
.dig(...keys)
Safely navigate nested arrays and hashes. Returns null on the first missing key or out-of-bounds index (instead of raising). Supports negative array indices.
# Works with arrays of hashes (very common after .all() or JSON)
data = [
{ "user": { "name": "Alice", "posts": [ { "title": "Hello" } ] } },
{ "user": { "name": "Bob" } }
]
print(data.dig(0, "user", "name")); # "Alice"
print(data.dig(0, "user", "posts", 0, "title")); # "Hello"
print(data.dig(1, "user", "posts", 0)); # null (safe)
print(data.dig(99, "user")); # null
# Also works on plain nested arrays
matrix = [[1, 2], [3, [4, 5]]]
print(matrix.dig(1, 1, 0)); # 4
print(matrix.dig(0, 5)); # null
# Negative indices are supported
print([10, 20, 30].dig(-1)); # 30
Why these take a field name, not a block. Each aggregate below names the field as data, so the entire traversal runs in Rust and never re-enters the interpreter. The hand-written equivalent — rows.reduce(fn(a, r) { return a + r["n"] }, 0) — calls back into Soli once per element and measures ~235× slower on 20,000 rows. Reach for these before writing the loop. See Benchmarks.
.sum_by(field)
Total a numeric field across an array of records. Integers stay integral — useful for money held as cents — and the result promotes to a float only once a float is seen. Missing or non-numeric fields are skipped rather than raising.
orders = [
{ "sku": "a", "cents": 1250 },
{ "sku": "b", "cents": 900 }
]
print(orders.sum_by("cents")); # 2150
# Mixed numeric types promote to Float
print([{ "n": 1.5 }, { "n": 2 }].sum_by("n")); # 3.5
# Missing fields are skipped, not errors
print(orders.sum_by("nope")); # 0
.group_by(field)
Group records by the value of a field, returning a hash of value → array of records. Key order follows first appearance, and records keep their original order within each group.
users = [
{ "name": "Alice", "role": "admin" },
{ "name": "Bob", "role": "member" },
{ "name": "Carol", "role": "admin" }
]
by_role = users.group_by("role")
print(by_role["admin"].len()); # 2
print(by_role.keys()); # ["admin", "member"]
.index_by(field)
Build a lookup hash of field value → record. The usual way to turn a list into something you can index in O(1). On a duplicate key the last record wins.
users = [
{ "id": 7, "name": "Alice" },
{ "id": 9, "name": "Bob" }
]
by_id = users.index_by("id")
print(by_id[7]["name"]); # "Alice"
.count_by(field)
Count records per distinct field value, returning value → count. The direct way to build dashboard tallies without a loop.
tickets = [
{ "status": "open" },
{ "status": "closed" },
{ "status": "open" }
]
print(tickets.count_by("status")); # {"open": 2, "closed": 1}
.tally()
Count occurrences of each value in a flat array, returning value → count. Like count_by, but for arrays of plain values rather than records.
print([1, 2, 2, 3].tally()); # {1: 1, 2: 2, 3: 1}
print(["a", "b", "a"].tally()); # {"a": 2, "b": 1}
.avg() / .avg_by(field)
Mean of a flat numeric array, or of one field across records. Always a Float — an average is a ratio, and integer division would report [2, 3].avg() as 2. An empty array averages to null, not 0, so "no data" stays distinguishable from a real zero mean.
print([2, 3].avg()); # 2.5, not 2
print([1, 2, 3, 4].avg()); # 2.5
scores = [{ "n": 90 }, { "n": 95 }]
print(scores.avg_by("n")); # 92.5
# Nothing to average is null, never a misleading zero
print([].avg()); # null
print([0].avg()); # 0
.filter_by(field, value) / .find_by(field, value)
Select records by a field value, using the same equality as ==. filter_by returns every match; find_by returns the first, or null. Same names and meaning as the model methods, so an in-memory filter and a database one read alike.
users = [
{ "name": "Alice", "role": "admin" },
{ "name": "Bob", "role": "member" },
{ "name": "Carol", "role": "admin" }
]
print(users.filter_by("role", "admin").pluck("name")); # ["Alice", "Carol"]
print(users.find_by("role", "member")["name"]); # "Bob"
print(users.find_by("role", "ghost")); # null
.uniq_by(field)
One record per distinct field value, keeping the first seen and preserving input order. The usual way to deduplicate a list by email, SKU or external id.
contacts = [
{ "email": "a@x.com", "src": "import" },
{ "email": "b@x.com", "src": "import" },
{ "email": "a@x.com", "src": "manual" }
]
# The first "a@x.com" survives; the later duplicate is dropped
print(contacts.uniq_by("email").pluck("src")); # ["import", "import"]
.max_by(field) / .min_by(field)
The record holding the largest or smallest value of a field — not the value itself. Records missing the field are skipped rather than comparing as null, so a partly-populated list still gives a useful answer; null when nothing carries the field. Ties keep the first seen.
players = [
{ "name": "Alice", "score": 30 },
{ "name": "Bob", "score": 25 },
{ "name": "Carol", "score": 30 }
]
print(players.max_by("score")["name"]); # "Alice" — first of the tied 30s
print(players.min_by("score")["name"]); # "Bob"
# A record with no score cannot win min_by by default
print(([{ "name": "Ghost" }] + players).min_by("score")["name"]); # "Bob"
.pluck(field, ...)
Extract one or more fields from an array of hashes or arrays. With a single field it returns a flat array of values. With multiple fields it returns an array of arrays (one row per element). Missing keys or out-of-bounds indices yield null.
posts = [
{ "id": 1, "title": "Hello", "author": "Alice" },
{ "id": 2, "title": "World", "author": "Bob" }
]
# Single field → flat array of values
titles = posts.pluck("title")
print(titles); # ["Hello", "World"]
# Multiple fields → array of arrays
rows = posts.pluck("id", "title")
print(rows); # [[1, "Hello"], [2, "World"]]
# Works with integer indices too (arrays of arrays)
matrix = [[10, "foo"], [20, "bar"]]
print(matrix.pluck(0)); # [10, 20]
print(matrix.pluck(0, 1)); # [[10, "foo"], [20, "bar"]]
# Missing keys are null (no crash)
print(posts.pluck("published_at")); # [null, null]
.pick(field, ...)
Return value(s) from the first element only (convenient “get one” helper). Single field returns a scalar (or null); multiple fields return an array. Empty receiver or missing keys on the first element yield null.
posts = [
{ "id": 1, "title": "Hello" },
{ "id": 2, "title": "World" }
]
print(posts.pick("title")); # "Hello"
print(posts.pick("id", "title")); # [1, "Hello"]
# On empty or when first element lacks the key
[].pick("title") # null
[{"name": "Alice"}].pick("email") # null
.sort / .sort(def)
Sort elements. Default is ascending order, or provide a custom comparator.
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# Default sort (ascending)
sorted = numbers.sort
print(sorted); # [1, 1, 2, 3, 4, 5, 6, 9]
# Custom comparator (descending)
desc = numbers.sort(|a, b| b - a)
print(desc); # [9, 6, 5, 4, 3, 2, 1, 1]
# Trailing block syntax
desc = numbers.sort |a, b| b - a end
# Sort by string length
words = ["cherry", "pie", "apple"]
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.
people = [
{ "name": "Charlie", "age": 30 },
{ "name": "Alice", "age": 25 },
{ "name": "Bob", "age": 20 }
]
# Sort by hash key (string argument)
by_name = people.sort_by("name")
print(by_name.map(|p| p.get("name"))); # [Alice, Bob, Charlie]
by_age = people.sort_by("age")
print(by_age.map(|p| p.get("age"))); # [20, 25, 30]
# Sort by function (for computed values)
words = ["cherry", "pie", "apple"]
by_length = words.sort_by(|w| len(w))
print(by_length); # [pie, apple, cherry]
.reverse
Return a new array with elements in reverse order.
arr = [1, 2, 3, 4, 5]
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.
arr = [1, 2, 2, 3, 3, 3, 4]
unique = arr.uniq
print(unique) # [1, 2, 3, 4]
.compact
Remove null values from the array.
arr = [1, null, 2, null, 3, null]
cleaned = arr.compact
print(cleaned) # [1, 2, 3]
.compact_blank
Remove null, empty strings, empty arrays, and empty hashes from the array.
arr = [1, null, "", [], {}, "hello", [1], {a: 1}]
cleaned = arr.compact_blank
print(cleaned) # [1, "hello", [1], {a: 1}]
.concat(other, ...)
Append the elements of one or more arrays to the receiver in place, then return the receiver. Unlike + (which builds a new array), .concat mutates the original — matching Ruby's Array#concat. Passed-in arrays are not modified. Raises if any argument is not an Array.
a = [1, 2]
a.concat([3, 4])
print(a); # [1, 2, 3, 4]
# Multiple arrays
nums = [1]
nums.concat([2, 3], [4, 5])
print(nums); # [1, 2, 3, 4, 5]
# Empty arg is a no-op
[1, 2].concat([]) # [1, 2]
# Returns the receiver, so chaining mutates the same array
arr = []
arr.concat([1, 2]).concat([3])
print(arr); # [1, 2, 3]
Set Operations
.intersection, .union, and .difference treat arrays as sets — they always return new, deduplicated arrays. The receiver and the argument are left untouched.
.intersection(other)
Returns a new array of elements present in both the receiver and other, in the order they appear in the receiver, with duplicates removed. Raises if the argument is not an Array.
[1, 2, 3].intersection([2, 3, 4]) # [2, 3]
["a", "b", "c"].intersection(["b", "d"]) # ["b"]
# Duplicates in the receiver collapse
[1, 1, 2, 2, 3].intersection([1, 2]) # [1, 2]
# No overlap returns an empty array
[1, 2, 3].intersection([4, 5, 6]) # []
# Empty receiver returns an empty array
[].intersection([1, 2]) # []
.union(other)
Returns a new array containing every element from the receiver followed by every new element from other, with duplicates removed. Raises if the argument is not an Array.
[1, 2, 3].union([2, 3, 4]) # [1, 2, 3, 4]
# Duplicates collapse — even within the receiver
[1, 1, 2].union([2, 3]) # [1, 2, 3]
# Empty other returns the deduped receiver
[1, 1, 2].union([]) # [1, 2]
# Order preserved: receiver first, then new elements from other
["a", "b"].union(["c", "a"]) # ["a", "b", "c"]
.difference(other)
Returns a new array of receiver elements that are not in other, with duplicates removed. Unlike -, the result is always deduplicated. Raises if the argument is not an Array.
[1, 2, 3].difference([2, 3]) # [1]
# Duplicates in the receiver collapse
[1, 1, 2, 2, 3].difference([3]) # [1, 2]
# All elements removed → empty array
[1, 2, 3].difference([1, 2, 3]) # []
# Empty other returns the deduped receiver
[1, 1, 2, 3].difference([]) # [1, 2, 3]
.flatten / .flatten(n)
Flatten nested arrays. Optionally specify depth.
nested = [[1, 2], [3, 4], [5, 6]]
flat = nested.flatten
print(flat); # [1, 2, 3, 4, 5, 6]
# Flatten only 1 level deep
deep = [[1, 2], [[3, 4]]]
partial = deep.flatten(1)
print(partial); # [1, 2, [3, 4]]
.first / .last
Get the first or last element.
arr = [10, 20, 30, 40, 50]
print(arr.first); # 10
print(arr.last); # 50
# Returns null for empty arrays
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.
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
empty = []
print(empty.empty?); # true
print(empty.blank?); # true
print(empty.present?); # false
.sample / .shuffle
Random element selection and shuffling.
arr = [1, 2, 3, 4, 5]
# Get random element
random = arr.sample
print(random); # Random element (e.g., 3)
# Shuffle array
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.
arr = [1, 2, 3, 4, 5]
# Take first n elements
first_three = arr.take(3)
print(first_three); # [1, 2, 3]
# Skip first n elements
rest = arr.drop(3)
print(rest); # [4, 5]
.slice(start?, end?)
Extract a sub-array by start and end index. Both arguments are optional and support negative indices counting from the end. Returns a new array (non-mutating).
arr = [1, 2, 3, 4, 5]
# Extract by start and end index
print(arr.slice(1, 3)); # [2, 3]
# Negative start (last n elements)
print(arr.slice(-2)); # [4, 5]
# Negative end (all but last n)
print(arr.slice(1, -1)); # [2, 3, 4]
# Out of bounds returns empty
print(arr.slice(5)); # []
# No args returns a copy
copy = arr.slice()
print(copy); # [1, 2, 3, 4, 5]
# Original unchanged
print(arr); # [1, 2, 3, 4, 5]
.zip(other)
Combine two arrays into pairs.
names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]
pairs = names.zip(scores)
# [["Alice", 95], ["Bob", 87], ["Charlie", 92]]
.sum / .min / .max
Numeric aggregation methods.
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.
words = ["Hello", "World"]
print(words.join(" ")); # "Hello World"
numbers = [1, 2, 3, 4, 5]
print(numbers.join("-")); # "1-2-3-4-5"
paths = ["usr", "local", "bin"]
print(paths.join("/")); # "usr/local/bin"
Method Chaining
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Chain multiple methods together
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
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.
arr = [1, 2, 3]
# In REPL, displays: [1, 2, 3]
# Equivalent to: arr.to_string
to_json
Serializes the array to a JSON string.
arr = [1, "hello", true, null]
arr.to_json # '[1,"hello",true,null]'
nested = [{name: "Alice"}, {name: "Bob"}]
nested.to_json # '[{"name":"Alice"},{"name":"Bob"}]'
.length / .len / .size
Returns the number of elements in the array.
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.
arr = []
arr.push(1) # [1]
arr.push(2) # [1, 2]
last = arr.pop # 2, arr is now [1]
get(index)
Returns the element at the specified index. Supports negative indices for backward access.
arr = ["first", "second", "third"]
arr.get(0); # "first"
arr.get(2); # "third"
arr.get(-1); # "third" (last)
arr.get(-2); # "second"
.delete(value) / .delete_at(index)
delete removes all elements equal to value — returns the mutated array or null if not found. delete_at removes the element at the given index (supports negative indices).
[1, 2, 3, 2].delete(2) # [1, 3]
[1, 2].delete(99) # null
[1, 2, 3].delete_at(1) # [1, 3]
[1, 2, 3].delete_at(-1) # [1, 2]
.shift / .unshift(value)
shift removes the first element. unshift prepends elements to the front. Both return a new array (strings are immutable).
[1, 2, 3].shift # [2, 3]
[].shift # null
[1, 2].unshift(0) # [0, 1, 2]
.insert(index, value, ...)
Inserts values at the given index. Supports negative indices. Multiple values can be inserted at once.
[1, 3].insert(1, 2) # [1, 2, 3]
[1, 4].insert(1, 2, 3) # [1, 2, 3, 4]
.rotate(count?)
Rotates the array by count positions (default 1). Positive moves elements from left to right; negative goes the other way.
[1, 2, 3].rotate # [2, 3, 1]
[1, 2, 3].rotate(2) # [3, 1, 2]
[1, 2, 3].rotate(-1) # [3, 1, 2]
.reject(def) / .none?(def) / .one?(def)
reject is the inverse of filter — keeps items where the block returns false. none? returns true if no items match. one? returns true if exactly one matches.
[1, 2, 3, 4].reject(fn(x) x % 2 == 0) # [1, 3]
[1, 2].none?(fn(x) x > 10) # true
[1, 2, 3].one?(fn(x) x == 2) # true
[1, 2, 2].one?(fn(x) x == 2) # false
.values_at(index, ...)
Returns an array containing values at the specified indices. Supports negative indices and arrays of indices.
[10, 20, 30, 40].values_at(0, 2) # [10, 30]
[10, 20, 30].values_at(0, -1) # [10, 30]
.count(value?)
With no argument returns the length. With an argument counts occurrences. With a function counts elements where the block returns truthy.
[1, 2, 3].count # 3
[1, 2, 2, 3].count(2) # 2
[1, 2, 3, 4].count(fn(x) x % 2 == 0) # 2
.class / .inspect / .nil? / .is_a?
Type introspection methods available on all types.
arr = [1, 2, 3]
arr.class # "array"
arr.inspect # "[1, 2, 3]"
arr.nil? # false
arr.is_a?("array") # true