Alexander Forbes-Reed
Alexander Forbes-Reed

Reputation: 2975

Delete first x entires of an array

I have an array of items, and I need to delete the first x items of it. Is there a built-in function in the Ruby Array class to do this? I had a search around and only found, what looked like, incredibly messy or inefficient ways to do it.

I'd preferably like something like this:

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
trimmed_items = my_items.delete(y, x) # deleting x entries from index y

Upvotes: 25

Views: 20081

Answers (4)

Daniel Viglione
Daniel Viglione

Reputation: 9427

For sake of completeness, I will add another method to achieve 'deleting first x entries of an array' and getting the remaining elements of array without affecting original array, which is how drop in the Enumerable module works:

arr = [1,2,3,4,5]
arr - arr[0..2]
 => [4, 5] 
arr
 => [1, 2, 3, 4, 5] 

In fact, [] is an alias for slice, as specified in the Array docs:

ary[index] → obj or nil
ary[start, length] → new_ary or nil
ary[range] → new_ary or nil
slice(index) → obj or nil
slice(start, length) → new_ary or nil
slice(range) → new_ary or nil

Now that I made my contribution, I do want to say I prefer drop and shift.

Since drop is an instance method of Enumerable, it can be applied to any object whose class implements Enumerable module, including Array and Hash. Hence, it is invoked on an Enumerable object. However, drop returns the remaining elements of the array. So it drops the specified elements and returns the rest:

[1,2,3,4,5].drop(2)
 => [3, 4, 5] 
{a: 'a', b: 'b', c: 'c'}.drop(2)
 => [[:c, "c"]] 

Notice that regardless of the Enumerable object, the return value is the remainder elements in an Array. As an answer already states, the original object is not mutated.

The shift method is implemented in Array and is not an Enumerable object and consequently can only be applied to Arrays. Shift returns the elements that were removed from the array and since it mutated the array itself, you can still access the remaining elements through the variable holding the array:

arr = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
arr.shift(2)
 => [1, 2] 
arr
 => [3, 4, 5] 

Ultimately, there are many ways to do this and it depends on what you want in the response and whether you mind if the array is mutated or not.

Upvotes: 2

Mark Rushakoff
Mark Rushakoff

Reputation: 258288

Yet another way to accomplish this: use Array#shift, which is particularly useful when you want the values that you're removing from the front of the array.

a = (1..5).to_a
a.shift(2)
a # => [3, 4, 5]

Upvotes: 4

Arup Rakshit
Arup Rakshit

Reputation: 118271

I have an array of items, and I need to delete the first x items of it.

To non-destructive deletion

Array#drop(x) will do the work for you.

Drops first n elements from ary and returns the rest of the elements in an array.If a negative number is given, raises an ArgumentError.

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
p my_items.drop(2)
p my_items

# >>["item3", "item4"]
# >>["item1", "item2", "item3", "item4"]

To destructive deletion

Array#shift

Removes the first element of self and returns it (shifting all other elements down by one). Returns nil if the array is empty.If a number n is given, returns an array of the first n elements (or less) just like array.slice!(0, n) does.

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
my_items.shift(2)
p my_items # => ["item3", "item4"]

Upvotes: 61

toro2k
toro2k

Reputation: 19228

To destructively update my_items you could do:

my_items.slice!(0, 2)
# => ["item1", "item2"] 
my_items
# => ["item3", "item4"] 

Upvotes: 3

Related Questions