gpt4 book ai didi

ruby - 这个 ruby 迭代器棘手的干净解决方案?

转载 作者:数据小太阳 更新时间:2023-10-29 06:45:35 25 4
gpt4 key购买 nike

k = [1,2,3,4,5]
for n in k
puts n
if n == 2
k.delete(n)
end
end
puts k.join(",")

# Result:
# 1
# 2
# 4
# 5
# [1,3,4,5]

# Desired:
# 1
# 2
# 3
# 4
# 5
# [1,3,4,5]

同样的效果发生在另一个数组迭代器 k.each 上:

k = [1,2,3,4,5]
k.each do |n|
puts n
if n == 2
k.delete(n)
end
end
puts k.join(",")

具有相同的输出。

发生这种情况的原因很清楚......Ruby 实际上并没有遍历存储在数组中的对象,而是只是将它变成一个漂亮的数组索引迭代器,从索引 0 开始,每次增加索引直到结束。但是当你删除一个项目时,它仍然会增加索引,所以它不会对同一个索引求值两次,而我希望它这样做。

可能不是正在发生的事情,但这是我能想到的最好的。

有没有一种干净的方法来做到这一点?是否已经有一个内置的迭代器可以做到这一点?还是我必须弄脏它并做一个数组索引迭代器,而不是在删除项目时递增? (或遍历数组的克隆,并从原始数组中删除)


澄清

我不只是想从数组中删除项目;对不起,如果那很清楚。我想做的是遍历每个元素,并“处理”它;这个过程有时可能会删除它。更准确地说:

class Living_Thing

def initialize tracker,id
@tracker = tracker
@id = id

@tracker << self
end

def process
do_stuff
puts @id
if @id == 2
die
end
end

def die
do_stuff_to_die
@tracker.delete(self)
end

def inspect
@id
end
end

tracking_array = Array.new()

foo = Living_Thing.new(tracking_array,1)
bar = Living_Thing.new(tracking_array,2)
rab = Living_Thing.new(tracking_array,3)
oof = Living_Thing.new(tracking_array,4)

puts tracking_array.join(",") # => [1, 2, 3, 4]

for n in tracking_array
n.process
end

# result: only foo, bar, and oof are processed

理想情况下,我希望处理 tracking_array 中的所有项目。

当 Living_Thing 从 tracking_array 中移除时,Living_Thing#die 必须被调用; do_stuff_to_die 清理必须清理的东西。

最佳答案

在大多数语言中,在迭代集合时改变集合是错误的。在大多数语言中,解决方案是创建一个副本并对其进行修改,或者构建一个索引列表,然后在完成迭代后对这些索引执行操作,但 Ruby 的迭代器为您提供的远不止于此。有几个解决方案是显而易见的。最地道的 IMO:

puts k
puts k.reject {|n| n == 2}.join(',')

更直接地从您的示例翻译:

k.delete_if do |n|
puts n
n == 2
end
puts k.join(',')

(delete_if 基本上是 reject 的破坏性版本,它返回 block 未返回 true 的对象数组。)

关于ruby - 这个 ruby 迭代器棘手的干净解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3002953/

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