Ruby无法删除数组中的元素

时间:2016-11-09 07:50:28

标签: 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
    end
    nums.length
end

remove_element(nums,3)

3 个答案:

答案 0 :(得分: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的副本上运行迭代,但结果与第二次迭代的结果相同 - 没有第二个要删除的元素。

答案 1 :(得分:3)

正如所评论的那样,你在迭代它时修改了数组,因为它删除了第一个元素,并结束了迭代。如果您在nums.each_with_index循环中放置打印状态,您将看到它只打印一次。

删除元素的更好方法可以是使用拒绝方法,如下所示:

nums.reject!{|item| item == 3}

答案 2 :(得分:2)

方法delete怎么样?

tree

delete_if

(define (insert f)
  (define (sub-insert t)
    (cond
      [(null? t) (make-tree f null null)]
      [(equal? f (value t)) t]
      [(< f (value t)) (make-tree (value t) (sub-insert (left t)) (right t))]
      [else            (make-tree (value t) (left t) (sub-insert (right t)))]))

  (set! tree (sub-insert tree))
  tree)

<强> UPD

nums = [3,3]
def remove_element(nums, val)
    nums.delete(val)
    nums.length
end
remove_element(nums, 3)
#=> 0