开发者

Array method that accepts an index and returns a new array with the item at the index removed

开发者 https://www.devze.com 2023-04-13 06:49 出处:网络
\'delete_at\' and \'slice\' remove the item at the index and return that item. But 开发者_StackOverflow社区I don\'t really care about the removed item. I just want a new array with that item removed.

'delete_at' and 'slice' remove the item at the index and return that item. But 开发者_StackOverflow社区I don't really care about the removed item. I just want a new array with that item removed. Ruby's Array class doesn't seem to provide such a method.

Example would be:

a = ['a','b','c','d']
b = a.remove(2) #b => ['a','b','d']

Here 'remove' is a fictitious method that does what I want. I need the original array, so I want a new array return. I wonder if Ruby already has some built-in like this?


class Array
  def remove(idx)
    self[0...idx] + self[idx+1..-1]
  end
end


    a = ['a','b','c','d']
    a.reject {|i|  i  == a[2] }  
#=> ["a", "b", "d"] 


irb(main):001:0> a = %w[ a b c d ]
#=> ["a", "b", "c", "d"]
irb(main):002:0> a.reject.with_index{ |o,i| i==2 }
#=> ["a", "b", "d"]
irb(main):003:0> a
#=> ["a", "b", "c", "d"]

Requires Ruby 1.9

With some monkey-patching:

irb(main):013:0> class Array
irb(main):014:1>   def remove_at(i)
irb(main):015:2>     self.dup.tap{ |clone| clone.delete_at(i) }
irb(main):016:2>   end
irb(main):017:1> end
#=> nil
irb(main):018:0> a.remove_at(2)
#=> ["a", "b", "d"]
irb(main):019:0> a
#=> ["a", "b", "c", "d"]


it's quite hacky:

a = ['a','b','c','d']
b, = [a, a.delete_at(0)] # => ['b','c','d']

but it's faster(on my eeepc)

require 'benchmark'

n = 5000
Benchmark.bm do |x|
  a = (1..5000).to_a
  b = nil
  x.report { n.times do; b, = [a, a.delete_at(0)]; end }
  a = (1..5000).to_a
  b = nil
  x.report { n.times do; b = a.reject.with_index{ |o,i| i == 0 }; end }
end

      user     system      total        real
  0.032000   0.000000   0.032000 (  0.034002)
 21.808000   0.156000  21.964000 ( 22.696298) OMG!
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号