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

czj · 2019年02月15日 · 最后由 sevk 回复于 2019年02月18日 · 1083 次阅读
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)?

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
需要 登录 后方可回复, 如果你还没有账号请 注册新账号