数组操作在原始数组上完成,而不是在副本上完成

时间:2017-02-14 09:56:01

标签: arrays ruby

我有一个这样的数组:

@array_a = ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

我希望@array_b@array_a类似,但不包含前两个元素,@array_a保持不变。我将第一个数组分配给第二个数组,并删除了一些元素:

@array_b = @array_a
@array_b.shift
@array_b.shift

@array_a@array_b都错过了前两个元素:

[85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

操作@array_a后如何让@array_b保持不变?

4 个答案:

答案 0 :(得分:2)

您可以在此使用 Object#dup

dup按值复制对象而不是按引用复制

    @array_a = ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

    O/P  => ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

    @array_b = @array_a.dup

    O/P  => ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

    @array_b.shift
    @array_b.shift

    @array_b:

    O/P => [85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

    @array_a:

    O/P  => ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

因此,在您将@array_a复制到@array_b并删除@array_b @array_a重新传输后的元素后

答案 1 :(得分:1)

您可以像这样创建一个新的Array对象:

@array_b = Array.new(@array_a)

Ruby不会创建新的数组对象,而是在分配给变量时重用相同的对象:

@array_a = Array.new
@array_a = ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]
#=> ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]
@array_a.object_id
#=> 2062
@array_b = @array_a
#=> ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]
@array_b.object_id
#=> 2062

这就是@array_b上的变异也反映在@array_a中的原因。

答案 2 :(得分:0)

此问题最简单的解决方案是使用下标运算符创建子数组并将其分配给@array_b

看起来像这样:

@array_a = ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0,   nil]
# => ["total", nil, 85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

@array_b = @array_a[2..-1]
# => [85.35, 85.97, 85.97, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil]

它创建一个从第三个元素(索引2)开始并以最后一个元素(索引-1)结束的子数组

答案 3 :(得分:-1)

您可以使用Ruby方法复制或克隆类对象。看看这个页面看看差异:

https://ruby-doc.org/core-2.4.0/Object.html#method-i-dup-label-on+dup+vs+clone