Reputation: 2975
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
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
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
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
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
Reputation: 19228
To destructively update my_items
you could do:
my_items.slice!(0, 2)
# => ["item1", "item2"]
my_items
# => ["item3", "item4"]
Upvotes: 3