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