Why .dup not work with multidimensional arrays?

Chris via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri May 8 08:09:50 PDT 2015


On Friday, 8 May 2015 at 06:30:46 UTC, Ali Çehreli wrote:
> 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

Nice one. I have the same problem in one of my modules. I might 
use the above code henceforth.


More information about the Digitalmars-d-learn mailing list