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