【问题标题】:Ruby delete_at changes another arrayRuby delete_at 更改另一个数组
【发布时间】:2014-12-21 20:14:34
【问题描述】:

在我程序中的一个数组上调用 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

【问题讨论】:

    标签: ruby arrays methods


    【解决方案1】:

    两个变量都引用内存中的同一个对象。 Array#delete_at 方法会改变您的数组,因此旧变量引用已变异的旧数组。

    另一方面,arr = arr[0..-2] 不会改变数组,它会返回一个新数组并将arr 局部变量分配给结果。这就是为什么其他引用没有改变。

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

    附:在 Ruby 中,方法参数是通过引用而不是值传递的。

    【讨论】:

    • 红宝石是否对所有数据类型都这样做?假设我应该在编程中避免这种类型的变量赋值是否安全?我问的唯一原因是因为我一直认为 var1 = var2 只是将值复制到 var1 中。这对某些但不是所有数据类型都是正确的吗?还是我离基地太远了
    • 是的。在 Ruby 中,如果要复制对象,则必须显式使用 dupclone
    【解决方案2】:

    all_pricescurrent_prices 这两个数组都只是指向原始数组prices 的指针。要将它们制作成单独的副本,您可以尝试以下方法:

    all_prices = prices.clone
    current_prices = prices.clone
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多