Array#delete

arr.delete(obj) -> obj or nil
Returns: Object or nil · Updated March 13, 2026 · Array Methods
ruby array mutation

The delete method removes all elements from an array that match a given object. Unlike delete_at which removes by index, delete searches by value and removes every occurrence. It returns the deleted value, or nil if nothing was found.

fruits = ["apple", "banana", "cherry", "banana"]
fruits.delete("banana")
# => "banana"
fruits
# => ["apple", "cherry"]

Syntax

arr.delete(obj)
arr.delete(obj) { block }

Parameters

ParameterTypeDescription
objObjectThe value to remove from the array
blockBlockOptional block evaluated if no match is found

Return Value

delete returns the deleted object if found, or nil if no matching elements exist. The block, if provided, is only evaluated when nothing is deleted:

arr = [1, 2, 3]

# Returns the deleted value
arr.delete(2)
# => 2
arr
# => [1, 3]

# Returns nil when not found (no block)
arr = [1, 2, 3]
arr.delete(99)
# => nil

# Block runs only when no match
arr = [1, 2, 3]
arr.delete(99) { "not found" }
# => "not found"

Removing Multiple Occurrences

delete removes all elements equal to the given object:

numbers = [1, 2, 3, 2, 4, 2]
numbers.delete(2)
# => 2
numbers
# => [1, 3, 4]

# Every "banana" is removed
items = ["a", "b", "a", "c", "a"]
items.delete("a")
# => "a"
items
# => ["b", "c"]

Common Use Cases

Cleaning User Input

# Remove unwanted values from user-submitted data
tags = ["ruby", "python", "", "java", nil, "ruby"]
tags.delete("")
# => ""
tags
# => ["ruby", "python", "java", nil, "ruby"]

tags.delete(nil)
# => nil
tags
# => ["ruby", "python", "java", "ruby"]

Removing Specific Items

# Filter out processed items
queue = ["task1", "task2", "task1", "task3"]
completed = "task1"

queue.delete(completed)
queue
# => ["task2", "task3"]

With Object Comparison

# Remove objects by custom equality
class Task
  attr_reader :name, :done
  
  def initialize(name, done: false)
    @name = name
    @done = done
  end
  
  def ==(other)
    other.is_a?(Task) && name == other.name
  end
end

tasks = [Task.new("buy milk"), Task.new("clean room"), Task.new("buy milk")]
tasks.delete(Task.new("buy milk"))
# => #<Task:0x00007f8a2c0c1a40 @name="buy milk", @done=false>
tasks
# => [#<Task:0x00007f8a2c0c1a38 @name="clean room">]

Comparing with Other Methods

MethodSearches ByRemovesReturns
deletevalueAll matchesDeleted value or nil
delete_atindexSingle elementDeleted element or nil
select!blockMultiple (keep truthy)self or nil
reject!blockMultiple (remove truthy)self or nil
compact-nil valuesnew array
arr = [1, 2, 3, 2, 4]

# delete by value
arr.delete(2)
# => 2
arr
# => [1, 3, 4]
arr = [1, 2, 3, 2, 4]

# delete_at by index
arr.delete_at(1)
# => 2
arr
# => [1, 3, 2, 4]

Gotchas

Using the Block for Defaults

The block only executes when no match is found, not when the value is nil:

# This is a common mistake
arr = [1, nil, 2]
arr.delete(nil) { "default" }
# => nil (not "default")
# Because nil was actually found and deleted

Reference Equality

Ruby uses == for comparison, not necessarily equal?:

# Different objects but equal values
"hello" == "hello"
# => true

arr = ["hello"]
arr.delete("hello")
# => "hello" (deleted!)

Return Value After Deletion

If you need the deleted value and the modified array, note that delete returns the value, not the array:

arr = [1, 2, 3]
deleted = arr.delete(2)
# => 2 (the value, not [1, 3])

# If you need both:
arr = [1, 2, 3]
deleted = arr[arr.index(2)]
arr.delete(2)
# => 2, arr is now [1, 3]

See Also