克隆多维数组

jak*_*kar 8 arrays clone raku

我想将多维数组克隆为@a数组@b

我以最直观的方式进行了操作,并提出了以下建议:

    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;
Run Code Online (Sandbox Code Playgroud)

打印出来的是:

    @a : [[0 1 0] [1 0 0] [0 0 0]]
    @b : [[0 1 0] [1 0 0] [0 0 0]]
Run Code Online (Sandbox Code Playgroud)

那意味着两个数组@a 和@b 是绑定的?

问题:

  1. 为什么数组@a 绑定到数组@b(在这种情况下clone 方法的目的是什么?我们知道clone 的行为与一维数组的意图相同)
  2. 我怎样才能真正将@a 克隆到@b(多维)?
  3. 哪个是最有效的方式(有时间限制)来做到这一点?

Jon*_*ton 10

你拥有的不是一个多维数组,而是一个数组数组。由于clone是浅层,它只会复制顶级数组。在这种情况下,clone也是多余的,因为分配给数组已经是一个复制操作。

一个简单的解决方法是克隆每个嵌套数组:

my @b = @a.map(*.clone);
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用真正的多维数组。声明将如下所示:

my @a[3;3] = [0, 0, 0], [0, 0, 0], [0, 0, 0];
Run Code Online (Sandbox Code Playgroud)

然后复制到另一个数组将是:

my @b[3;3] = @a;
Run Code Online (Sandbox Code Playgroud)

作业也需要更新以使用多维语法:

@a[0;1] = 1;
@b[1;0] = 1;
Run Code Online (Sandbox Code Playgroud)

最后,这个结果:

say '@a : ' ~ @a.gist;
say '@b : ' ~ @b.gist;
Run Code Online (Sandbox Code Playgroud)

是否符合要求:

@a : [[0 1 0] [0 0 0] [0 0 0]]
@b : [[0 0 0] [1 0 0] [0 0 0]]
Run Code Online (Sandbox Code Playgroud)

作为最后的清理,您还可以将概念上无限的0s序列“倒入”数组以对其进行初始化:

my @a[3;3] Z= 0 xx *;
Run Code Online (Sandbox Code Playgroud)

这意味着不需要在右侧复制 3x3 结构。

  • @ikarpenis @Larry 在[维基百科意义上](https://en.wikipedia.org/wiki/Variable_(computer_science))中使用标量(小写“s”)和“标量”(大写“S”)来表示[Raku的标准内置标量*容器*](https://docs.raku.org/type/Scalar)。“标量”从来都不是数组;但它可以*包含*(对)“Array”的引用。赋值“@a[0][1] = ...”不会更改标量或“标量”“@a[0]”,并且不会在“标量”容器中放置新的“数组” `@a[0]` 也可以。它只是更改绑定到“@a[0]”的现有“Scalar”中保存的现有“Array”中第二个“Scalar”中保存的值。 (2认同)

Hol*_*lli 5

@a@b没有约束。它们只是碰巧包含相同的东西。在clone不进行递归并且仅克隆外阵列。

实现您想要的一种方法是

@b = @a.map: *.clone; 
Run Code Online (Sandbox Code Playgroud)