gpt4 book ai didi

arrays - Ruby delete_if 数组子集

转载 作者:太空宇宙 更新时间:2023-11-03 17:44:39 26 4
gpt4 key购买 nike

我有一个数组,我想执行 delete_if在该数组的一个子集(任何 n 项)上(并且它修改内存中的数组)

有了完整的阵列我可以做到

array.delete_if do |item|
should_be_deleted?(item)
end

如果我想限制为前 n 项,则以下将不起作用

array.take(n).delete_if do |item|
should_be_deleted?(item)
end

因为它将创建一个新数组并执行 delete_if在那个新阵列上

是否有替代方案,例如 take_and_delete_if这将只删除前 n 个项目(如果该 block 对每个项目都返回 true)?

编辑:

我想处理数组 ab , c以 3 为一组(并在执行操作后从数组中删除)

by_batch_of(3, until: (proc { a.empty? })) do 
# This sets an instance variable @by = 3, and will iterate as long as `a` has any item
process_from_a # Will move @by items in a to either array b or c or fail
process_from_b # Will move @by items in b to c or fail
process_from_c # Should move items or fail and put back in a
end

sample 处理方法

process_from_a(by: @by)
a.take_and_delete_if(by: by) do |item| # The +take_and_delete_if+ methods is the one I need
b << item if reason1
c << item if reason2
reason1 or reason2 # Delete if the item was moved away
end

我要的是性能

例子

a = [1,2,3,4,5,6,7,8,9]
b = []
c = []

第一批 3 个

  • process_from_a(作者:3)

    a = [3,4,5,6,7,8,9] # 3 failed so delete_if returned false, it remains in the array (order doesn't matter)
    b = [1] # 1 moved to b
    c = [2] # 2 moved to c
  • process_from_b

    a = [3,4,5,6,7,8,9]
    b = []
    c = [1,2] # 2 moved to c
  • process_from_c

    a = [3,4,5,6,7,8,9,1] # 1 was rejected in a
    b = []
    c = [] # 1,2 processed from c

例如,下一次迭代将从 a 等处理 [3,4,5]。

性能

假设我的数组非常大(10k、100k)并且我想要按 10 个批处理处理项目。我不希望使用昂贵的解决方案来过滤前 10 个项目并使用 index < 10 删除整个数组。 ...

最佳答案

应该可以做一个 in place replacement使用来自子集的过滤元素:

a = (0..10000).to_a;
a[0, 100] = a[0, 100].delete_if(&:odd?)

基准:

require 'benchmark/ips'

Benchmark.ips do |x|
x.report("with_index") { (0..10000).to_a.delete_if.with_index { |k, i| k.odd? && i < 100 } }
x.report("slice") { a = (0..10000).to_a; a[0, 100] = a[0, 100].delete_if(&:odd?) }

x.compare!
end

在 MRI Ruby 2.4.0p0 上给出这些结果:

Warming up --------------------------------------
with_index 58.000 i/100ms
slice 273.000 i/100ms
Calculating -------------------------------------
with_index 602.354 (± 6.6%) i/s - 3.016k in 5.033200s
slice 2.775k (±10.0%) i/s - 13.923k in 5.075605s

Comparison:
slice: 2774.9 i/s
with_index: 602.4 i/s - 4.61x slower

关于arrays - Ruby delete_if 数组子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42576693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com