Delete array contents based on index set

delete_at accepts only one index. What is a good way to achieve this using inline methods? It doesn't have to be a set; it can also be an array of indices.

arr = ["a", "b", "c"] set = Set.new [1, 2] arr.delete_at set # => arr = ["a"] 
+6
source share
4 answers

Single line:

 arr.delete_if.with_index { |_, index| set.include? index } 
+12
source

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 do not want to reopen the class. Make sure that indexes in the reverse order are very important, otherwise you will reposition the elements later in the array to be deleted.

+4
source

Try the following:

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

This is a little ugly, I think;) Maybe someone will suggest a better solution?

+1
source

Functional approach:

 class Array def except_values_at(*indexes) ([-1] + indexes + [self.size]).sort.each_cons(2).flat_map do |idx1, idx2| self[idx1+1...idx2] || [] end end end >> ["a", "b", "c", "d", "e"].except_values_at(1, 3) => ["a", "c", "e"] 
0
source

Source: https://habr.com/ru/post/900492/


All Articles