新手问题 数组变量重新接受赋值后 object_id 改变

czj · 2019年02月15日 · 最后由 sevk 回复于 2019年02月18日 · 649 次阅读
irb(main):399:0> a = [1,2]
=> [1, 2]
irb(main):400:0> b = [3,4]
=> [3, 4]
irb(main):401:0> a.object_id
=> 47275352718560       #a的原id
irb(main):402:0> b.object_id
=> 47275352706000
irb(main):403:0> a = a[0,1] + b[0,1]
=> [1, 3]
irb(main):404:0> a.object_id
=> 47275352402160    #a接受新赋值后新的id

如何最简洁的将新值 a[0,1] + b[0,1] 赋给 (=> 47275352718560 #a的原id)?

共收到 7 条回复

a.slice!(1..-1) a.push(*b[0,1])

这是我用的方法, 但要做 a[n,m] + b[n,m] 就比较麻烦

Array的+方法返回的是新对象,对象id当然会变。

你写的解决方法是OK的,我不明白为什么处理a[n, m] + b[n, m]会麻烦:

a.slice!(n,m)
a.push(*b[n,m])
spike76 回复
irb(main):516:0> a=[0,1,2,3,4,5,6]
=> [0, 1, 2, 3, 4, 5, 6]
irb(main):517:0> b=[1,1,1,2,2]
=> [1, 1, 1, 2, 2]
irb(main):518:0> a[3,2] + b[3,2]
=> [3, 4, 2, 2]                                #**********想要的a的元素
irb(main):519:0> a.slice!(3,2)
=> [3, 4]
irb(main):520:0> a.push(*b[3,2])
=> [0, 1, 2, 5, 6, 2, 2]
irb(main):521:0> a
=> [0, 1, 2, 5, 6, 2, 2]                     #***********a的元素与想要的[3, 4, 2, 2]  不同

如上,两行注释 不等呀!

a.slice!(n,m)是在a中删除元素[n,m], 不是使得a变为原a的[n,m]

变量标识符是没有object_id的。

对象是有id的。

你把新的对象赋值给变量标识符,对象的id当然会改变。

czj 回复

对哦,搞错slice!的副作用了。那就用两次slice!

a.tap{|arr| arr.slice!((n + m)..-1)}.tap{|arr| arr.slice!(0, n)}.push(*b[n,m])

其实直接用keep_if或者delete!看起来更简单

a.keep_if.with_index {|_, idx| idx >= n && idx < (n + m)}.push(*b[n,m])
a[1] = b[0]

可以用 << 替代 +

a=[]; p a.object_id;  10000.times{ a << 1 } ; p a.object_id
47043160719720
47043160719720
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册