6

Given a Ruby array ary1, I'd like to produce another array ary2 that has the same elements as ary1, except for those at a given set of ary1 indices.

I can monkey-patch this functionality onto Ruby's Array class with

class Array
  def reject_at(*indices)
    copy = Array.new(self)
    indices.uniq.sort.reverse_each do |i|
      copy.delete_at i
    end
    return copy
  end
end

which I can then use like this:

ary1 = [:a, :b, :c, :d, :e]
ary2 = ary1.reject_at(2, 4)
puts(ary2.to_s) # [:a, :b, :d]

While this works fine, I have the feeling that I must be missing something obvious. Is there some functionality like this already built into Ruby? E.g., can and should Array#slice be used for this task?

das-g
  • 9,718
  • 4
  • 38
  • 80

3 Answers3

14

Don't think there is an inbuilt solution for this. Came up with the following:

ary1 = [:a, :b, :c, :d, :e]
indexes_to_reject = [1,2,3]

ary1.reject.each_with_index{|i, ix| indexes_to_reject.include? ix }
fylooi
  • 3,840
  • 14
  • 24
  • Ah, nice! This answer helped me to finally understand [`Enumerator`](http://ruby-doc.org/core-2.2.2/Enumerator.html) chaining. – das-g May 26 '15 at 13:00
2

For the opposite, there is Array#values_at. You can use that by inverting the indices to select:

class Array
  def values_without(*indices)
    values_at(*((0...size).to_a - indices))
  end
end

[:a, :b, :c, :d, :e].values_without(2, 4)
# => [:a, :b, :d]
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
0

You can use reject.with_index.

ary1 = [:a, :b, :c, :d, :e]

ary1.reject.with_index { _2.in?([2,4]) }
=> [:a, :b, :d]
Al17
  • 431
  • 7
  • 20
  • Using the [`with_index` Enumerator](https://apidock.com/ruby/Enumerator/with_index) is very elegant! The [`in?` method](https://apidock.com/rails/Object/in%3F) though [is in `ActiveSupport` (part of Rails)](https://stackoverflow.com/a/10601055/674064), so in plain Ruby this won't work without additional dependencies. However `ary1.reject.with_index { [2,4].include? _2 }` can be used instead. Do you want to [edit] your question to include that? – das-g Sep 29 '22 at 13:13