2-D array initialization

tastyminerals tastyminerals at gmail.com
Sun Aug 2 06:37:06 UTC 2020


On Sunday, 2 August 2020 at 02:00:46 UTC, Andy Balba wrote:
> On Saturday, 1 August 2020 at 22:00:43 UTC, Ali Çehreli wrote:
>> On 8/1/20 12:57 PM, Andy Balba wrote:
>>
>> > On Saturday, 1 August 2020 at 00:08:33 UTC, MoonlightSentinel
>> wrote:
>> >> On Friday, 31 July 2020 at 23:42:45 UTC, Andy Balba wrote:
>> >>> How does one initialize c in D ?
>> >>
>> >> ubyte[3][4] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35,
>> 35,35]  ];
>>
>> > I'm a D newbie. moving over from C/C++, and I'm really
>> finding it hard
>> > to adjusting to D syntax, which I find somewhat cryptic
>> compared to C/C++.
>>
>> That's surprising to me. I came from C++03 year ago but 
>> everything in D was much better for me. :)
>>
>> I wanted to respond to your question yesterday and started 
>> typing some code but then I decided to ask first: Do you 
>> really need a static array? Otherwise, the following is a 
>> quite usable 2D array:
>>
>>   ubyte[][] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35, 
>> 35,35]  ];
>>
>> However, that's quite different from a ubyte[3][4] static 
>> array because 'c' above can be represented like the following 
>> graph in memory. (Sorry if this is already known to you.)
>>
>> c.ptr --> | .ptr | .ptr | .ptr | .ptr |
>>               |      |      |      |
>>               .      .      |       --> | 35 | 35 | 35 | 35 |
>>              etc.   etc.     --> | 25 | 25 | 25 | 25 |
>>
>> In other words, each element is reached through 2 dereferences 
>> in memory.
>>
>> On the other hand, a static array consists of nothing but the 
>> elements in memory. So, a ubyte[3][4] would be the following 
>> elements in memory:
>>
>>   | 5 | 5 | ... | 35 | 35 |
>>
>> One big difference is that static arrays are value types, 
>> meaning that all elements are copied e.g. as arguments during 
>> function calls. On the other hand, slices are copied just as 
>> fat pointers (ptr+length pair), hence have reference semantics.
>>
>> Here are some ways of initializing a static array. This one is 
>> the most natural one:
>>
>>   ubyte[3][4] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35, 
>> 35,35]  ];
>>
>> Yes, that works! :) Why did you need to cast to begin with? 
>> One reason may be you had a value that could not fit in a 
>> ubyte so the compiler did not agree. (?)
>>
>> This one casts a 1D array as the desired type:
>>
>>   ubyte[3][4] c = *cast(ubyte[3][4]*)(cast(ubyte[])[ 5, 5, 5, 
>> 15, 15, 15, 25, 25, 25, 35, 35, 35 ]).ptr;
>>
>> The inner cast is required because 5 etc. are ints by-default.
>>
>> There is std.array.staticArray as well but I haven't used it.
>>
>> Ali
>
> Although not detailed in my original question, in my actual app
> I have array ubyte [1000][3] Big which consists of research 
> data I obtained,
>  and from which I want to randomly select 4 observations to 
> construct
> ubyte c[ ][ ].
>
> i.e. construct c= [ Big[r1][3], Big[r2][3], Big[r3][3], 
> Big[r4][3] ]
> where r1, r2, r3 and r4 are 4 random integers in 0..1001
>
> Being a D newbie, my naive way of doing this was to declare c 
> using:
> ubyte[3][4] c= [ Big[r1][3], Big[r2][3], Big[r3][3], Big[r4][3] 
> ]
>
> Obviously, I want to learn how to this the smart D way, but I 
> not smart enough at this point.

You haven't said anything about efficiency because if you care 
and your arrays are rather big, you better go with 
https://github.com/libmir/mir-algorithm as mentioned above. It 
might be a little finicky at the start but this post: 
https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html should get you up to speed.


Keep in mind that std.array.staticArray is not efficient for 
large arrays.

If you want to stick to standard D, I would not initialize a 2D 
array because it is just cumbersome but rather use a 1D array and 
transform it into 2D view on demand via ".chunks" method. Here is 
an example.

import std.range;
import std.array;

void main() {
     int[] arr = 20.iota.array;
     auto arr2dView = arr.chunks(5);
}

Should give you

┌              ┐
│ 0  1  2  3  4│
│ 5  6  7  8  9│
│10 11 12 13 14│
│15 16 17 18 19│
└              ┘

whenever you need to access its elements as arr.chunks(5)[1][1 .. 
3] --> [6, 7].



More information about the Digitalmars-d-learn mailing list