如何将阵列的唯一副本推送到另一个阵列?

时间:2015-08-21 04:53:28

标签: arrays ruby

我正在尝试将子集推入数组:

def subsets(arr)
    subsets = [[]]
    temp_arr = []
    i = 0
    while i < arr.length
        temp_arr << arr[i]
        subsets << temp_arr
        p subsets
        i+=1
    end
    return subsets
end

我的结果如下:

[[], ["a"]]
[[], ["a", "b"], ["a", "b"]]
[[], ["a", "b", "c"], ["a", "b", "c"], ["a", "b", "c"]]

为什么每次将temp_array推送到子集数组时,推送temp_array的先前结果也会发生变化?

有没有办法可以推送temp_array的唯一实例并将其保持在该状态?

另外,任何人都可以给我一个关于如何从数组中获取所有子集的提示吗?

2 个答案:

答案 0 :(得分:2)

subsets << temp_arr

temp_arr对实际Array对象的引用。在此之后,附加到subsetstemp_arr的元素都引用同一个对象。

如果这不符合您的预期,请使用dup获取其副本:

subsets << temp_arr.dup

答案 1 :(得分:1)

问题是您将同一个对象temp_arr推送到subsets

Ruby通常不会复制数据,它会传递对象的引用。 subsets << temp_arrtemp_arr引用到subsets,而不是temp_arr当前发生的任何内容。

subsets[0] -> temp_arr
subsets[1] -> temp_arr
subsets[2] -> temp_arr

要避免这种情况,您需要制作copy of temp_arr并将其推送到subsets

while i < arr.length
    temp_arr << arr[i]
    subsets << temp_arr.clone
    p subsets
    i+=1
end

另外,使用each可以更好地编写循环。

arr.each { |element|
    temp_arr << element
    subsets << temp_arr.clone
    p subsets
}

或者使用array slice完全避免使用temp变量。

arr.each_index { |idx|
    subsets << arr[0..idx]
    p subsets
}