Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Problem with copying array

Reply
Thread Tools

Problem with copying array

 
 
jbieger@gmail.com
Guest
Posts: n/a
 
      12-24-2007
Hi, I'm a total newbie with Ruby and I was trying to make this
function that would get a (multidimensional) array, make a copy, make
some changes to the copy and then return the copy, without altering
the original array. However, no matter what I try, the original array
gets altered. Here is my code:

def prune_times (times)
# copy = times
# copy = Array.new(times)
# copy = times.clone
copy = times.dup
copy.each do |map|
map.each do |task|
task.replace(best_n(task, 2))
end
end
return copy
end

Any help would be greatly appreciated!

Jordi
 
Reply With Quote
 
 
 
 
Bryan Duxbury
Guest
Posts: n/a
 
      12-24-2007
What's your array an array of? Array.dup will copy the array to a new
array, but if the values in the array are references to some class
you're using, it'll be a different array of the same items.
Primitives would be copied correctly. You need to do your own deep
copy if it's a more complicated array value.

-Bryan

On Dec 24, 2007, at 7:19 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> Hi, I'm a total newbie with Ruby and I was trying to make this
> function that would get a (multidimensional) array, make a copy, make
> some changes to the copy and then return the copy, without altering
> the original array. However, no matter what I try, the original array
> gets altered. Here is my code:
>
> def prune_times (times)
> # copy = times
> # copy = Array.new(times)
> # copy = times.clone
> copy = times.dup
> copy.each do |map|
> map.each do |task|
> task.replace(best_n(task, 2))
> end
> end
> return copy
> end
>
> Any help would be greatly appreciated!
>
> Jordi
>



 
Reply With Quote
 
 
 
 
jbieger@gmail.com
Guest
Posts: n/a
 
      12-24-2007
Thanks for your reply!

Like I said, it's a multidimensional array, so I suppose that the
contents aren't primitive and I need to do as you suggested. Is there
a built-in function for this, or do I need to make my own. It seems
like a pretty common operation...

Jordi

On 24 dec, 16:50, Bryan Duxbury <(E-Mail Removed)> wrote:
> What's your array an array of? Array.dup will copy the array to a new
> array, but if the values in the array are references to some class
> you're using, it'll be a different array of the same items.
> Primitives would be copied correctly. You need to do your own deep
> copy if it's a more complicated array value.
>
> -Bryan
>
> On Dec 24, 2007, at 7:19 AM, (E-Mail Removed) wrote:
>
> > Hi, I'm a total newbie with Ruby and I was trying to make this
> > function that would get a (multidimensional) array, make a copy, make
> > some changes to the copy and then return the copy, without altering
> > the original array. However, no matter what I try, the original array
> > gets altered. Here is my code:

>
> > def prune_times (times)
> > # copy = times
> > # copy = Array.new(times)
> > # copy = times.clone
> > copy = times.dup
> > copy.each do |map|
> > map.each do |task|
> > task.replace(best_n(task, 2))
> > end
> > end
> > return copy
> > end

>
> > Any help would be greatly appreciated!

>
> > Jordi


 
Reply With Quote
 
Frederick Cheung
Guest
Posts: n/a
 
      12-24-2007

On 24 Dec 2007, at 16:05, (E-Mail Removed) wrote:

> Thanks for your reply!
>
> Like I said, it's a multidimensional array, so I suppose that the
> contents aren't primitive and I need to do as you suggested. Is there
> a built-in function for this, or do I need to make my own. It seems
> like a pretty common operation...


You need to do it yourself. It may be pretty common, but the exact
specifics of how deep to go etc... tend to be rather application
dependant.

Fred
>
>
> Jordi
>
> On 24 dec, 16:50, Bryan Duxbury <(E-Mail Removed)> wrote:
>> What's your array an array of? Array.dup will copy the array to a new
>> array, but if the values in the array are references to some class
>> you're using, it'll be a different array of the same items.
>> Primitives would be copied correctly. You need to do your own deep
>> copy if it's a more complicated array value.
>>
>> -Bryan
>>
>> On Dec 24, 2007, at 7:19 AM, (E-Mail Removed) wrote:
>>
>>> Hi, I'm a total newbie with Ruby and I was trying to make this
>>> function that would get a (multidimensional) array, make a copy,
>>> make
>>> some changes to the copy and then return the copy, without altering
>>> the original array. However, no matter what I try, the original
>>> array
>>> gets altered. Here is my code:

>>
>>> def prune_times (times)
>>> # copy = times
>>> # copy = Array.new(times)
>>> # copy = times.clone
>>> copy = times.dup
>>> copy.each do |map|
>>> map.each do |task|
>>> task.replace(best_n(task, 2))
>>> end
>>> end
>>> return copy
>>> end

>>
>>> Any help would be greatly appreciated!

>>
>>> Jordi

>
>



 
Reply With Quote
 
Matthew Harris
Guest
Posts: n/a
 
      12-24-2007
(E-Mail Removed) wrote:
> Thanks for your reply!
>
> Like I said, it's a multidimensional array, so I suppose that the
> contents aren't primitive and I need to do as you suggested. Is there
> a built-in function for this, or do I need to make my own. It seems
> like a pretty common operation...
>
> Jordi
>
> On 24 dec, 16:50, Bryan Duxbury <(E-Mail Removed)> wrote:
>
>> What's your array an array of? Array.dup will copy the array to a new
>> array, but if the values in the array are references to some class
>> you're using, it'll be a different array of the same items.
>> Primitives would be copied correctly. You need to do your own deep
>> copy if it's a more complicated array value.
>>
>> -Bryan
>>
>> On Dec 24, 2007, at 7:19 AM, (E-Mail Removed) wrote:
>>
>>
>>> Hi, I'm a total newbie with Ruby and I was trying to make this
>>> function that would get a (multidimensional) array, make a copy, make
>>> some changes to the copy and then return the copy, without altering
>>> the original array. However, no matter what I try, the original array
>>> gets altered. Here is my code:
>>>
>>> def prune_times (times)
>>> # copy = times
>>> # copy = Array.new(times)
>>> # copy = times.clone
>>> copy = times.dup
>>> copy.each do |map|
>>> map.each do |task|
>>> task.replace(best_n(task, 2))
>>> end
>>> end
>>> return copy
>>> end
>>>
>>> Any help would be greatly appreciated!
>>>
>>> Jordi
>>>

>
>
>
>

Your methods of copying the array are correct (though, you should remove
one and only use the other, which ever). The problem is that with some
objects, Ruby doesn't know how to "copy" them.

Bryan already mentioned this, but for primitives like strings, integers,
floats and whatnot, Ruby knows how to copy these objects, but if you
have custom classes or other classes that don't define their own
behavior for copying, then Ruby will keep the reference.

Hope that helps.

--
Matthew Harris
http://matthewharris.org


 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      12-24-2007

On Dec 24, 2007, at 07:19 , (E-Mail Removed) wrote:

> Hi, I'm a total newbie with Ruby and I was trying to make this
> function that would get a (multidimensional) array, make a copy, make
> some changes to the copy and then return the copy, without altering
> the original array. However, no matter what I try, the original array
> gets altered. Here is my code:


`ri Enumerable#map`


 
Reply With Quote
 
Sebastian Hungerecker
Guest
Posts: n/a
 
      12-25-2007
Matthew Harris wrote:
> Bryan already mentioned this, but for primitives like strings, integers,
> floats and whatnot, Ruby knows how to copy these objects


Strings can be copied with the dup method, yes. But if you mean to imply that
that happens automatically when dupping an array of Strings, you are wrong:
>> arr=["chunky", "bacon"]
>> arr.dup.each {|str| str.tr!("ck","kc")}
>> arr

=> ["khuncy", "bakon"]

Integers and Floats can not be copied at all:
>> 5.dup

TypeError: can't dup Fixnum

>> 5.0.dup

TypeError: allocator undefined for Float

> but if you
> have custom classes or other classes that don't define their own
> behavior for copying, then Ruby will keep the reference.


If you dup an array you will always get a new array with references to the old
objects. dup never makes a deep copy.
Presumably there is no built-in way to make a deep copy because, as mentioned
above, some objects (like Integers) can't be copied.


I hope this cleared the confusion a bit,
Sebastian
--
Jabber: (E-Mail Removed)
ICQ: 205544826

 
Reply With Quote
 
Sebastian Hungerecker
Guest
Posts: n/a
 
      12-25-2007
Bryan Duxbury wrote:
> What's your array an array of? Array.dup will copy the array to a new
> array, but if the values in the array are references to some class
> you're using, it'll be a different array of the same items.
> Primitives would be copied correctly. You need to do your own deep
> copy if it's a more complicated array value.


a) There are no primitives in ruby. Everything is an object.
b) Array#dup never makes a deep copy. You'll always get a different array of
the same items no matter what the class of these items is.


HTH,
Sebastian
--
Jabber: (E-Mail Removed)
ICQ: 205544826

 
Reply With Quote
 
Jan Dvorak
Guest
Posts: n/a
 
      12-25-2007
On Monday 24 December 2007 16:19:59 (E-Mail Removed) wrote:
> Hi, I'm a total newbie with Ruby and I was trying to make this
> function that would get a (multidimensional) array, make a copy, make
> some changes to the copy and then return the copy, without altering
> the original array. However, no matter what I try, the original array
> gets altered. Here is my code:


Another possibility is serialization - it's still your job to make your
classes serializable and there is stuff that cannot be serialized, but for
simple cases (multi-dimensional arrays) it works out-of-box:

irb(main):001:0> a = [["a","b"],[1,2]]
=> [["a", "b"], [1, 2]]
irb(main):002:0> b = Marshal.load(Marshal.dump(a))
=> [["a", "b"], [1, 2]]
irb(main):003:0> b[0][0], b[1][0] = "x", 9
=> ["x", 9]
irb(main):004:0> a
=> [["a", "b"], [1, 2]]
irb(main):005:0> b
=> [["x", "b"], [9, 2]]

Jan

 
Reply With Quote
 
Alan Slater
Guest
Posts: n/a
 
      10-30-2008
Highly related newbie question, please pardon the non-technical
language.

So, arrays (even arrays of 'primitives' like strings) don't actually
contain the objects that fill each entry, they instead (effectively)
link to those objects. So, .delete_at and .slice! (for example) don't
remove things from the array, they delete the objects that are being
linked to completely.

This explains my problem (why, whenever I delete an entry from an array,
it also deletes it from every copy of the array).

So, how could I simply remove an object from an array, without deleting
the object itself? Something like, array_name.remove_at(x) (except
obviously that doesn't exist).

I've been through the API and can't find anything that seems to fit. I
tried array_name[x] = nil, but that just left an empty entry and didn't
change the length of the array. Even that seems to change the original
object to nil too, as following array_name[x] = nil with
array.delete_at(x) removes the equivalent entry from the original array
as well.

How can I remove an entry from an array without deleting the object that
the entry refers to?
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Copying one array to another array janus C Programming 16 02-03-2010 09:20 PM
Copying array to an array, I really thought I knew what was going on. DaTurk C++ 2 09-11-2007 12:04 AM
Re: array copying to another array John Harrison C++ 2 07-15-2003 06:22 AM
Re: array copying to another array Thomas Matthews C++ 0 07-13-2003 06:13 PM
Re: array copying to another array MiniDisc_2k2 C++ 1 07-13-2003 02:35 PM



Advertisments