How to refer the index of an element in Array#delete_if

天大地大妈咪最大 提交于 2019-12-09 19:43:49

问题


I want to build a custom method Array#drop_every(n) (I know it's monkey patching, I am doing this for a homework), which returns a new array omitting every nth element:

[4, 8, 15, 16, 23, 42].drop_every(2) # [4, 15, 23]

I want to implement it with Array#delete_if, but by referring to the index and not to the element itself, (similar to each_index) something like this:

def drop_every(step)
  self.delete_if { |index| index % step == 0 }
end

How do I do this? I don't insist on using delete_if, I also looked at drop_while and reject, other suggestions are welcome.


回答1:


def drop_every(step)
  reject.with_index { |x,i| (i+1) % step == 0 }
end

[4, 8, 15, 16, 23, 42].reject.with_index{|x,i| (i+1) % 2 ==  0}
# => [4, 15, 23]

[4, 8, 15, 16, 23, 42].reject.with_index{|x,i| (i+1) % 3 ==  0}
# => [4, 8, 16, 23] 



回答2:


You can use with_index method that returns enumerator, filter your collection and then get rid of the indexes.

class Array
  def drop_every(step)
    self.each.with_index.select { |_, index| index % step == 0 }.map(&:first)
  end
end

[4, 8, 15, 16, 23, 42].drop_every(2) # => [4, 15, 23]



回答3:


You could use the values_at method to selectively filter out indices which you want.

class Array
  def drop_every(step)
    self.values_at(*(0...self.size).find_all{ |x| (x+1) % step != 0 })
  end    
end

The answer was accepted while I was typing it. I will post it anyways.




回答4:


def drop_every step
  delete_if.with_index(1){|_, i| i.%(step).zero?}
end



回答5:


class Array
  def drop_every(step)
    self.each_slice(step).flat_map{|slice| slice[0..-2]}
  end
end

p [4, 8, 15, 16, 23, 42].drop_every(2) #=> [4, 15, 23]



回答6:


I'd extend the Enumerable mixin instead:

module Enumerable
  def drop_every(step)
    return to_enum(:drop_every, step) unless block_given?
    each.with_index(1) do |o, i|
      yield o unless i % step == 0
    end
  end
end

(1..10).drop_every(3) { |a| p a }
# outputs below
1
2
4
5
7
8
10


来源:https://stackoverflow.com/questions/19317782/how-to-refer-the-index-of-an-element-in-arraydelete-if

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!