Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete contents of array based on a set of indexes

Tags:

ruby

delete_at only takes a single index. What's a good way to achieve this using built-in methods? Doesn't have to be a set, can be an array of indexes as well.

arr = ["a", "b", "c"]
set = Set.new [1, 2]
arr.delete_at set
# => arr = ["a"]
like image 734
Morrowless Avatar asked Nov 01 '11 09:11

Morrowless


3 Answers

One-liner:

arr.delete_if.with_index { |_, index| set.include? index }
like image 186
Victor Deryagin Avatar answered Oct 26 '22 13:10

Victor Deryagin


Re-open the Array class and add a new method for this.

class Array

  def delete_at_multi(arr)
    arr = arr.sort.reverse # delete highest indexes first.
    arr.each do |i|
      self.delete_at i
    end
    self
  end

end

arr = ["a", "b", "c"]
set = [1, 2]

arr.delete_at_multi(set)

arr # => ["a"]

This could of course be written as a stand-alone method if you don't want to re-open the class. Making sure the indexes are in reverse order is very important, otherwise you change the position of elements later in the array that are supposed to be deleted.

like image 41
Douglas F Shearer Avatar answered Oct 26 '22 13:10

Douglas F Shearer


Try this:

arr.reject { |item| set.include? arr.index(item) }  # => [a]

It's a bit ugly, I think ;) Maybe someone suggest a better solution?

like image 42
WarHog Avatar answered Oct 26 '22 15:10

WarHog