Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Ruby无法删除数组中的元素_Arrays_Ruby - Fatal编程技术网

Arrays Ruby无法删除数组中的元素

Arrays Ruby无法删除数组中的元素,arrays,ruby,Arrays,Ruby,对于下面的代码片段。 我想从数组中删除等于3的元素。 但是代码只删除了第一个元素。调试代码时, 我发现迭代器只在数组中循环一次而不是两次。 我不确定是什么导致了这个问题。任何帮助都将不胜感激 nums = [3,3] def remove_element(nums, val) nums.each_with_index do |num,index| if num == val nums.slice!(index) end en

对于下面的代码片段。
我想从数组中删除等于3的元素。 但是代码只删除了第一个元素。调试代码时,
我发现迭代器只在数组中循环一次而不是两次。
我不确定是什么导致了这个问题。任何帮助都将不胜感激

nums = [3,3]
def remove_element(nums, val)
    nums.each_with_index do |num,index|
        if num == val
            nums.slice!(index)
        end
    end
    nums.length
end

remove_element(nums,3)

正如@steenslag所指出的,
delete
方法将实现您想要的功能:

n = [1,2,3,3,4,5,6,3,4,5,3,2,1,8]
n.delete(3)
n
返回:
[1,2,4,5,6,4,5,2,1,8]

值得一看的是,除了您的代码之外,还有以下替代方案:

nums = [3,3]
def remove_element(nums, val)
    nums.each_with_index do |num,index|
        nums_before_slice = nums.clone
        if num == val
            sliced = nums.slice!(index)
        end
        puts "nums: #{nums_before_slice}, index: #{index}, sliced: #{sliced.inspect}"
    end
end

remove_element(nums,3)

puts "Result: #{nums.inspect}"
输出将是:

nums: [3, 3], index: 0, sliced: 3
Result: [3]
如您所见,迭代只发生一次,因为在进行第二次迭代之前,第二个元素已被删除

将该结果与此版本的代码进行比较:

nums = [3,3]
def remove_element(nums, val)
    nums.clone.each_with_index do |num,index|
        nums_before_slice = nums.clone
        if num == val
            sliced = nums.slice!(index)
        end
        puts "nums: #{nums_before_slice}, index: #{index}, sliced: #{sliced.inspect}"
    end
end

remove_element(nums,3)

puts "Result: #{nums.inspect}"
其结果是:

nums: [3, 3], index: 0, sliced: 3
nums: [3], index: 1, sliced: nil
Result: [3]

现在,这将在原始
nums
的副本上运行迭代,但结果与第二次迭代相同-没有要删除的第二个元素

正如正确评论的那样,您在迭代时修改了数组,因此它删除了第一个元素,并结束了迭代。如果您在
nums.内放置一个打印语句,每个带有索引的循环,您将看到它只打印一次

删除图元的更好方法是使用以下拒绝方法:

nums.reject!{|item| item == 3}
方法呢

还是

UPD

require 'benchmark'

array = Array.new(100000) { rand(5) }

Benchmark.bm do |x|
  x.report("delete: ") { array.delete(5) }
  x.report("delete_if: ") { array.delete_if { |e| e == 5 } }
  x.report("reject: ") { array.reject! { |e| e == 5 } }
end

#            user       system     total        real
# delete:    0.000000   0.000000   0.000000 (  0.004230)
# delete_if: 0.010000   0.000000   0.010000 (  0.006387)
# reject:    0.010000   0.000000   0.010000 (  0.007543)

不要在迭代数组时试图修改它。枚举数发疯了。不要修改你正在迭代的同一个数组。@mudasobwa谢谢,你能告诉我原因吗?这个问题在这个网站上已经被问过很多次了。第一次迭代在索引0处。您将删除该元素。现在,过去位于索引1的元素位于索引0,过去位于索引2的元素位于索引1,依此类推。下一次迭代在索引1处,它是过去位于索引2处的元素。看见已跳过以前位于索引1的元素。在您的情况下,整个过程在1次迭代后已经停止,因为在第一次迭代后,数组的大小是1,因此在第二次迭代中没有可以访问的索引1。@JörgWMittag非常有用谢谢,您能告诉我为什么在删除第一次迭代后迭代器停止吗element@MarcoSong,我认为迭代器在内部一直在寻找下一个要迭代的项,当您删除第一个元素时,迭代器在第二个元素上,但它没有找到下一个元素并返回。检查这里:谢谢你的帮助。非常容易理解。
n.delete(3)
@steenslag是-删除是另一个(可能更好)选项。是的,我从leetcode看到了这个解决方案。它真的很强大而且干净。但是代码运行速度不是很快,我认为delete方法的工作方式可能不是很有效,也不是很慢all@MarcoSong我很高兴:)下次您可以使用upd中的示例检查方法速度之间的差异:)
nums = [3,3]
def remove_element(nums, val)
    nums.delete_if { |element| element == val }
    nums.length
end
remove_element(nums, 3)
#=> 0
require 'benchmark'

array = Array.new(100000) { rand(5) }

Benchmark.bm do |x|
  x.report("delete: ") { array.delete(5) }
  x.report("delete_if: ") { array.delete_if { |e| e == 5 } }
  x.report("reject: ") { array.reject! { |e| e == 5 } }
end

#            user       system     total        real
# delete:    0.000000   0.000000   0.000000 (  0.004230)
# delete_if: 0.010000   0.000000   0.010000 (  0.006387)
# reject:    0.010000   0.000000   0.010000 (  0.007543)