Jump to page: 1 2
Thread overview
Initialization of dynamic multidimensional array
Feb 05, 2017
berni
Feb 05, 2017
Daniel Kozak
Feb 06, 2017
berni
Feb 06, 2017
Daniel Kozak
Feb 07, 2017
berni
Feb 10, 2017
berni
Feb 10, 2017
Daniel Kozak
Feb 10, 2017
berni
Feb 10, 2017
berni
Feb 10, 2017
Mike Parker
Feb 06, 2017
Ali Çehreli
Feb 07, 2017
Ilya Yaroshenko
February 05, 2017
With X not known at compile time:

> auto arr = new int[][](X,X);
> for (int i=0;i<X;i++)
>   for (int j=0;j<X;j++)
>     arr[i][j] = -1;

Is there anything better for this? I mean, the program will fill the array with zeroes, just to overwrite all of them with -1. That's wasted execution time and doesn't feel D-ish to me.
February 05, 2017
http://stackoverflow.com/questions/24600796/d-set-default-value-for-a-struct-member-which-is-a-multidimensional-static-arr/24754361#24754361


Dne 5.2.2017 v 21:33 berni via Digitalmars-d-learn napsal(a):
> With X not known at compile time:
>
>> auto arr = new int[][](X,X);
>> for (int i=0;i<X;i++)
>>   for (int j=0;j<X;j++)
>>     arr[i][j] = -1;
>
> Is there anything better for this? I mean, the program will fill the array with zeroes, just to overwrite all of them with -1. That's wasted execution time and doesn't feel D-ish to me.

February 06, 2017
On Sunday, 5 February 2017 at 21:14:33 UTC, Daniel Kozak wrote:
> http://stackoverflow.com/questions/24600796/d-set-default-value-for-a-struct-member-which-is-a-multidimensional-static-arr/24754361#24754361
>
>
> Dne 5.2.2017 v 21:33 berni via Digitalmars-d-learn napsal(a):
>> With X not known at compile time:
>>
>>> auto arr = new int[][](X,X);
>>> for (int i=0;i<X;i++)
>>>   for (int j=0;j<X;j++)
>>>     arr[i][j] = -1;
>>
>> Is there anything better for this? I mean, the program will fill the array with zeroes, just to overwrite all of them with -1. That's wasted execution time and doesn't feel D-ish to me.

Thanks for the link. Looks a little bit hacky... I hoped for something more straightforward, or at least, if direct initialisation is not possible something like "arr[][] = -1;" or "arr[0..X][0..X] = -1;" But as far as I can see now, this does not exist.
February 06, 2017
One another way is use something like this:
import std.array, std.algorithm, std.stdio;
auto arr = uninitializedArray!(int[][])(ROWS,COLS);
arr.each!"a[]=-1";
writeln(arr);

Dne 6. 2. 2017 8:21 PM napsal uživatel "berni via Digitalmars-d-learn" < digitalmars-d-learn@puremagic.com>:

> On Sunday, 5 February 2017 at 21:14:33 UTC, Daniel Kozak wrote:
>
>> http://stackoverflow.com/questions/24600796/d-set-default- value-for-a-struct-member-which-is-a-multidimensional- static-arr/24754361#24754361
>>
>>
>> Dne 5.2.2017 v 21:33 berni via Digitalmars-d-learn napsal(a):
>>
>>> With X not known at compile time:
>>>
>>> auto arr = new int[][](X,X);
>>>> for (int i=0;i<X;i++)
>>>>   for (int j=0;j<X;j++)
>>>>     arr[i][j] = -1;
>>>>
>>>
>>> Is there anything better for this? I mean, the program will fill the array with zeroes, just to overwrite all of them with -1. That's wasted execution time and doesn't feel D-ish to me.
>>>
>>
> Thanks for the link. Looks a little bit hacky... I hoped for something more straightforward, or at least, if direct initialisation is not possible something like "arr[][] = -1;" or "arr[0..X][0..X] = -1;" But as far as I can see now, this does not exist.
>


February 06, 2017
On 02/05/2017 12:33 PM, berni wrote:
> With X not known at compile time:
>
>> auto arr = new int[][](X,X);
>> for (int i=0;i<X;i++)
>>   for (int j=0;j<X;j++)
>>     arr[i][j] = -1;
>
> Is there anything better for this? I mean, the program will fill the
> array with zeroes, just to overwrite all of them with -1. That's wasted
> execution time and doesn't feel D-ish to me.

Here is something that returns the tail as dynamic array. (Otherwise, being a value type, the whole static array would be copied out of the function):

template makeMulDim(dims...) {
    template MultDimType(T, dims...) {
        static if (dims.length == 0) {
            alias MultDimType = T;
        } else static if (dims.length == 1) {
            alias MultDimType = T[];
        } else {
            alias MultDimType = MultDimType!(T[dims[0]], dims[1..$]);
        }
    }

    auto makeMulDim(T)(T initValue) {
        import std.algorithm : fold;

        const elementCount = [ dims ].fold!((a, b) => a * b);
        auto storage = new T[](elementCount);
        storage[] = initValue;
        return cast(MultDimType!(T, dims))storage;
    }
}

unittest {
    auto arr = makeMulDim!(2, 3, 4)(1.1);
    static assert (is (typeof(arr) == double[2][3][]));
}

void main() {
    import std.stdio;

    auto arr = makeMulDim!(2, 3, 4)(-1);
    pragma(msg, typeof(arr));
    arr[3][2][1] = 42;
    writefln("%(%s\n%)", arr);
}

So, the returned type in main is int[2][3][].

Ali

February 07, 2017
On Sunday, 5 February 2017 at 20:33:06 UTC, berni wrote:
> With X not known at compile time:
>
>> auto arr = new int[][](X,X);
>> for (int i=0;i<X;i++)
>>   for (int j=0;j<X;j++)
>>     arr[i][j] = -1;
>
> Is there anything better for this? I mean, the program will fill the array with zeroes, just to overwrite all of them with -1. That's wasted execution time and doesn't feel D-ish to me.

You may want to used new ndslice for multidimensional algorithms
http://docs.algorithm.dlang.io/latest/mir_ndslice.html


February 07, 2017
> auto arr = uninitializedArray!(int[][])(ROWS,COLS);
> arr.each!"a[]=-1";

This looks like what I was looking for. At least I think I understand what's going on here. The other two suggestions are beyond my scope yet, but I'll come back, when I improved on my D skills. Thanks for your replies.

February 10, 2017
On Tuesday, 7 February 2017 at 19:06:22 UTC, berni wrote:
>> auto arr = uninitializedArray!(int[][])(ROWS,COLS);
>> arr.each!"a[]=-1";
>
> This looks like what I was looking for. At least I think I understand what's going on here. The other two suggestions are beyond my scope yet, but I'll come back, when I improved on my D skills. Thanks for your replies.

Now I tried this with a named instead of a magic constant e.g.

> immutable VALUE=-1;
> arr.each!"a[]=VALUE";

And it doesn't work anymore. I've no clue, why... Can you help me?
February 10, 2017
Dne 10.2.2017 v 10:03 berni via Digitalmars-d-learn napsal(a):

> On Tuesday, 7 February 2017 at 19:06:22 UTC, berni wrote:
>>> auto arr = uninitializedArray!(int[][])(ROWS,COLS);
>>> arr.each!"a[]=-1";
>>
>> This looks like what I was looking for. At least I think I understand what's going on here. The other two suggestions are beyond my scope yet, but I'll come back, when I improved on my D skills. Thanks for your replies.
>
> Now I tried this with a named instead of a magic constant e.g.
>
>> immutable VALUE=-1;
>> arr.each!"a[]=VALUE";
>
> And it doesn't work anymore. I've no clue, why... Can you help me?
Because it does not see VALUE, you need to use delegate insted of string something like this:

arr.each!(a=>a[]=VALUE);


February 10, 2017
On Friday, 10 February 2017 at 09:03:16 UTC, berni wrote:

>
> Now I tried this with a named instead of a magic constant e.g.
>
>> immutable VALUE=-1;
>> arr.each!"a[]=VALUE";
>
> And it doesn't work anymore. I've no clue, why... Can you help me?

each is a template. As per the template documentation [1], your instantiation of each knows nothing about VALUE, because VALUE declared in the scope in which the template is instantiated. Template instantiations only have the scope in which they are implemented, not where they are instantiated, so here each cannot see VALUE.

On an side note (unrelated to your error), when declaring constants that are intended to be symbolic (i.e. you never need to take their address), it's more idiomatic to use manifest constants (via enum) rather than immutable.

enum value = -1;

[1] https://dlang.org/spec/template.html#instantiation_scope
« First   ‹ Prev
1 2