我有两个数组,一个包含数据,另一个包含索引。我想知道是否有一些很好的方法可以删除data
中indexes
中给出的位置中的元素。我可以做简单的迭代,但我想知道最短的方法是什么:
data = ['a','b','c','a','b','c','a','b','c']
indexes = [2,5,8]
//some code here
当索引恰好与数组索引中的数字一致时,data
中的元素消失了。它应该是这样的:
['a','b','a','b','a','b']
答案 0 :(得分:5)
data.values_at(*data.each_index.to_a - indexes)
# => ["a", "b", "a", "b", "a", "b"]
答案 1 :(得分:4)
我将按以下方式进行:
data = ['a','b','c','a','b','c','a','b','c']
indexes = [2,5,8]
data.values_at(*(0...data.size).to_a - indexes)
# => ["a", "b", "a", "b", "a", "b"]
答案 2 :(得分:4)
不经迭代地完成它可能看起来是一个很好的目标,但正确完成迭代将会非常快。
基准非常重要:
require 'benchmark'
DATA = ['a','b','c','a','b','c','a','b','c']
INDEXES = [2,5,8]
def ttm(data)
d2 = data.dup
INDEXES.sort.reverse.each{ |i| d2.delete_at(i) }
d2
end
def devon_parsons(data)
new_data = data.each_with_index.reject do |value,index|
INDEXES.include? index
end.map(&:first)
new_data
end
def arup_rakshit(data)
data.values_at(*(0...data.size).to_a - INDEXES)
end
def sawa(data)
data.values_at(*data.each_index.to_a - INDEXES)
end
确保它是苹果对苹果的测试:
ttm(DATA) # => ["a", "b", "a", "b", "a", "b"]
devon_parsons(DATA) # => ["a", "b", "a", "b", "a", "b"]
arup_rakshit(DATA) # => ["a", "b", "a", "b", "a", "b"]
sawa(DATA) # => ["a", "b", "a", "b", "a", "b"]
运行基准测试:
n = 100_000
Benchmark.bm(13) do |b|
b.report('ttm:') { n.times { ttm(DATA) } }
b.report('devon_parsons') { n.times { devon_parsons(DATA) } }
b.report('arup_rakshit') { n.times { arup_rakshit(DATA) } }
b.report('sawa') { n.times { sawa(DATA) } }
end
结果是:
# >> user system total real
# >> ttm: 0.130000 0.000000 0.130000 ( 0.127559)
# >> devon_parsons 0.530000 0.000000 0.530000 ( 0.535929)
# >> arup_rakshit 0.250000 0.000000 0.250000 ( 0.255295)
# >> sawa 0.300000 0.010000 0.310000 ( 0.305376)
如果数据大小增加:
DATA2 = DATA * 100
Benchmark.bm(13) do |b|
b.report('ttm:') { n.times { ttm(DATA2) } }
b.report('devon_parsons') { n.times { devon_parsons(DATA2) } }
b.report('arup_rakshit') { n.times { arup_rakshit(DATA2) } }
b.report('sawa') { n.times { sawa(DATA2) } }
end
结果确实发生了变化:
# >> user system total real
# >> ttm: 0.320000 0.090000 0.410000 ( 0.420074)
# >> devon_parsons 39.170000 0.080000 39.250000 ( 39.265062)
# >> arup_rakshit 9.950000 0.010000 9.960000 ( 9.975699)
# >> sawa 9.940000 0.020000 9.960000 ( 9.959036)
测试阵列大小变化时发生的事情非常重要。随着阵列的增长,在小阵列上快速运行的内容会急剧减慢。而且,通常情况下,做某事的好方法变得非常缓慢,因为存在隐性成本。基准测试帮助我们解决这些问题。
注意:使用sort.reverse
非常重要。没有这些,阵列将被破坏。
sort可以进一步改进为sort_by(&:本身)
require 'benchmark'
array = (0..99).to_a.shuffle
n = 100_000
Benchmark.bm(7) do |b|
b.report('sort:') { n.times { array.sort } }
b.report('sort_by:') { n.times { array.sort_by(&:itself) } }
end
导致:
user system total real
sort: 0.460000 0.010000 0.470000 ( 0.480236)
sort_by: 3.600000 0.030000 3.630000 ( 3.627871)
增加数组大小:
array = (0..999).to_a.shuffle
Benchmark.bm(13) do |b|
b.report('sort:') { n.times { array.sort } }
b.report('sort_by:') { n.times { array.sort_by(&:itself) } }
end
导致:
user system total real
sort: 9.520000 0.120000 9.640000 ( 9.659246)
sort_by: 53.530000 0.720000 54.250000 ( 54.321285)
答案 3 :(得分:1)
new_data = data.each_with_index.reject do |value,index|
indexes.include? index
end.map(&:first)
这次实际有效的新答案 - 它在O(n ^ 2)中运行,并且我没有看到这样做的方法而根本没有迭代索引。