Why .dup not work with multidimensional arrays?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu May 7 23:30:44 PDT 2015


On 05/07/2015 07:39 PM, Dennis Ritchie wrote:
> On Friday, 8 May 2015 at 02:23:23 UTC, E.S. Quinn wrote:
>> It's because arrays are references types, and .dup is a strictly
>> shallow copy, so you're getting two outer arrays that reference
>> the same set of inner arrays. You'll have to duplicated each of
>> the inner arrays yourself if you need to make a deep copy.
>
> Thank you. It really works :)
>
> -----
> import std.stdio;
>
> void main() {
>
>      auto c = [[[1, 2, 3], [4, 5, 6, 7, 8]],
>            [[9, 10], [11, 12, 13]]];
>
>      auto d = [[c[0][0].dup, c[0][1].dup],
>            [c[1][0].dup, c[1][1].dup]];
>
>      d[0][1][1 .. $ - 1] *= 3;
>
>      writeln("c = ", c);
>      // [[[1, 2, 3], [4, 5, 6, 7, 8]],
>      //  [[9, 10], [11, 12, 13]]] // OK
>      writeln("d = ", d);
>      // [[[1, 2, 3], [4, 15, 18, 21, 8]],
>      //  [[9, 10], [11, 12, 13]]] // OK
> }
> -----
> http://ideone.com/kJVUhd
>
> Maybe there is a way to create .globalDup for multidimensional arrays?

In D, everything is possible and very easy. :p I called it deepDup:

import std.stdio;
import std.traits;
import std.range;
import std.algorithm;

auto deepDup(A)(A arr)
     if (isArray!A)
{
     static if (isArray!(ElementType!A)) {
         return arr.map!(a => a.deepDup).array;

     } else {
         return arr.dup;
     }
}

void main()
{
     auto c = [[[1, 2, 3], [4, 5, 6, 7, 8]],
           [[9, 10], [11, 12, 13]]];

     auto d = c.deepDup;

     d[0][1][1 .. $ - 1] *= 3;

     writeln("c = ", c);
     // [[[1, 2, 3], [4, 5, 6, 7, 8]],
     //  [[9, 10], [11, 12, 13]]] // OK
     writeln("d = ", d);
     // [[[1, 2, 3], [4, 15, 18, 21, 8]],
     //  [[9, 10], [11, 12, 13]]] // OK
}

Ali



More information about the Digitalmars-d-learn mailing list