Ruby: drop elements in-place from the beginning of the Array and return the remaining array

StackOverflow https://stackoverflow.com/questions/19722667

  •  02-07-2022
  •  | 
  •  

Pergunta

Is there a method in Ruby that removes the first n items from an Array (or other Enumerable), changes the array variable, and returns the remaining elements of the array, as opposed to the elements that were removed?

Basically I'm looking for something like this:

a = ["r", "u", "b", "y"]
a.mystery_function!(2)
# => ["b", "y"]
puts a
# => ["b", "y"]

a.drop isn't what I want as that doesn't alter the value of a. a.shift isn't right either as in the above example it would return ["r", "u"] instead of ["b", "y"].

Foi útil?

Solução

Yes.. possible using Object#tap and Array#shift.

a = ["r", "u", "b", "y"]
p a.tap{|i| i.shift(2)}
# >> ["b", "y"]
p a
# >> ["b", "y"]

If you want to monkey-patch the class Array.

class Array
  def mystery_function!(n)
     shift(n);self
  end
end
a = ["r", "u", "b", "y"]
p a.mystery_function!(2)
# >> ["b", "y"]
p a
# >> ["b", "y"]

Outras dicas

a = ["r", "u", "b", "y"]
a.replace(a.drop(2)) # => ["b", "y"]
a # => ["b", "y"]

Or, maybe you can define one:

class Array
  def drop! n; replace(drop(n)) end
end

a = ["r", "u", "b", "y"]
a.drop!(2) # => ["b", "y"]
a # => ["b", "y"]

since you want to delete from the beginning of the array, it can be

a = ["r", "u", "b", "y"]
a.each_with_index{ |v,i| a.delete_at(0) if i < 2 }  #=> 2 is the no.of elements to be deleted from the beginning.    
=> ["b", "y"]

putting everything into its place ...

class Array
  def mystery_function!(x=nil)
    each_with_index{ |v,i| delete_at(0) if i < x }
  end
end

a = ["r", "u", "b", "y"]
a.mystery_function!(2)
puts a #=> ["b", "y"]

Having said the above, I feel using shift (as given in other answers) appear much more elegant.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top