Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloning multidimensional arrays

Tags:

arrays

clone

raku

I want to clone a multidimensional array @a to an array @b.

I've proceeded with the most intuitive way and I came up with the following:

    my @a = [0, 0, 0], [0, 0, 0], [0, 0, 0];

    my @b = @a.clone;

    @a[0][1] = 1;
    @b[1][0] = 1;

    say '@a : ' ~ @a.gist;
    say '@b : ' ~ @b.gist;

and the print out is:

    @a : [[0 1 0] [1 0 0] [0 0 0]]
    @b : [[0 1 0] [1 0 0] [0 0 0]]

That means that the two arrays @a and @b are binded?

Questions:

  1. Why array @a is binded to array @b (What is the purpose of the clone method in this situation? We know that clone behave as intented for one-dimensional arrays)
  2. How can I really clone @a to @b (multidimensional)?
  3. Which is the most efficient way (time bounded) to do that?
like image 563
jakar Avatar asked Dec 11 '19 14:12

jakar


People also ask

How do you clone a multidimensional array?

1. Using clone() method. A simple solution is to use the clone() method to clone a 2-dimensional array in Java. The following solution uses a for loop to iterate over each row of the original array and then calls the clone() method to copy each row.

What happens when a multi dimensional array is cloned in Java?

By using Java's clone() method, when a two dimensional array is cloned a new list of objects pointing to rows is created. Each object from this list further points to the same location where the original array's row object points. Therefore, when you do cloneArri[0] = null; .

Can you clone an array?

Answer: There are different methods to copy an array. You can use a for loop and copy elements of one to another one by one. Use the clone method to clone an array. Use arraycopy() method of System class.


2 Answers

What you have is not a multi-dimensional array, but rather an array of arrays. Since clone is shallow, it will just copy the top-level array. In this case, the clone is also redundant, since assignment into an array is already a copying operation.

A simple fix is to clone each of the nested arrays:

my @b = @a.map(*.clone);

Alternatively, you could use a real multi-dimensional array. The declaration would look like this:

my @a[3;3] = [0, 0, 0], [0, 0, 0], [0, 0, 0];

And then the copying into another array would be:

my @b[3;3] = @a;

The assignments also need updating to use the multi-dimensional syntax:

@a[0;1] = 1;
@b[1;0] = 1;

And finally, the result of this:

say '@a : ' ~ @a.gist;
say '@b : ' ~ @b.gist;

Is as desired:

@a : [[0 1 0] [0 0 0] [0 0 0]]
@b : [[0 0 0] [1 0 0] [0 0 0]]

As a final cleanup, you can also "pour" an conceptually infinite sequence of 0s into the array to initialize it:

my @a[3;3] Z= 0 xx *;

Which means that the 3x3 structure does not need to be replicated on the right.

like image 178
Jonathan Worthington Avatar answered Oct 24 '22 03:10

Jonathan Worthington


@a and @b are not bound. They just happen to contain the same things. The clone does not recurse and only clones the outer Array.

One way to achieve what you want would be

@b = @a.map: *.clone; 
like image 35
Holli Avatar answered Oct 24 '22 05:10

Holli