Ruby delete_at更改了另一个数组

时间:2014-10-26 14:45:47

标签: ruby arrays methods

在程序中的一个数组上调用delete_at后,它会同时改变另一个数组。这两个数组具有相同的值,但应该作为两个单独的事物处理(改变一个不应该改变另一个)。

请注意,我使用arr = arr [0 ..- 2]而不是arr.delete_at(-1)修复了解决方案。我只是想知道为什么delete_at改变了两个数组。

另请注意,我知道这可能不是解决手头谜题的最佳解决方案,但这不是我们在此讨论的内容;)

def stock_picker(prices)
#takes an array of stock prices by day and returns the best day to buy and sell

#this solution starts at the last day and finds the greatest difference, then drops the last day and does it again 
#until there is just one day left.
def pick(all_prices, current_prices, current_pick)
    if current_prices == 1
        return current_pick
    else

        new_pick = tryer(all_prices, current_prices, [0, current_prices.size-1])

        puts "all_prices"
        puts all_prices

        if (all_prices[new_pick.last] - all_prices[new_pick.first]) > (all_prices[current_pick.last] - all_prices[current_pick.first])
            current_pick = new_pick
        end

        current_prices.delete_at(-1)
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
        puts "After current_prices.delete_at(-1)"
        puts "all_prices"
        puts all_prices
        puts "current_prices"
        puts current_prices
        puts "wtf"
        return pick(all_prices, current_prices, current_pick)
    end
end

def tryer(all_prices, tryer_prices, tryer_pick)
    #subtracts the last day from each day.

    if tryer_prices.size == 1
        return tryer_pick
    else
        #the new pick reflects the first and last of the tryer_prices.
        new_pick = [tryer_pick.first + 1, tryer_pick.last]

        if (tryer_prices.last - tryer_prices.first) > (all_prices[tryer_pick.last] - all_prices[tryer_pick.first])

         return tryer(all_prices, tryer_prices.drop(1), new_pick)
        else
          return tryer(all_prices, tryer_prices.drop(1), tryer_pick)
        end

    end

end

all_prices = prices
current_prices = prices
pick(all_prices, current_prices, [0, prices.size-1])

end

result = stock_picker([17,3,6,9,15,8,6,1,10])
puts result

2 个答案:

答案 0 :(得分:2)

两个变量都引用内存中的同一个对象。 Array#delete_at方法会改变你的数组,所以旧的变量引用了变异的旧数组。

另一方面,arr = arr[0..-2]不会改变数组,它会返回新数组并将arr局部变量赋给结果。这就是为什么其他参考文献没有改变的原因。

如果要创建原始数组的副本,可以使用Object#dup方法。

P.S。在Ruby方法中,params是通过引用传递的,而不是通过值传递的。

答案 1 :(得分:1)

两个数组all_pricescurrent_prices都只是原始数组prices的指针。要使它们成为单独的副本,您可以尝试以下操作:

all_prices = prices.clone
current_prices = prices.clone

免责声明:我从未使用过Ruby,但这是许多不同语言的常见问题。所以我可能没有正确使用clone方法(也许dup会更好?),但方法是正确的:制作原始数组的独立副本,因此更改为一个不会影响原始数组其他