Aendur
Aendur

Reputation: 53

Initializing an array with an arbitrary number of elements in D

I have stumbled upon an issue when working with arrays in D. I need to initialize an array with an arbitrary number of elements of a pre-defined value.

I know it can be done like double[10] arr = 5;, for example, this will make an array with 10 elements of value 5. The problem, however, is that I need the number of elements passed on during the program's execution. I thought it could be done this way:

void test(immutable int x)
{
    double[x] arr = 5;
    writeln(arr);
}
void main() { test(10); }

But this causes Error: variable x cannot be read at compile time during compilation.

While it could be done by making a dynamic array and appending elements through a for loop, I think this may be rather inefficient (please correct me if I am wrong). So the question is, is there another efficient way to create an array with an arbitrary number of elements?

Upvotes: 2

Views: 389

Answers (2)

Abstract type
Abstract type

Reputation: 1921

You could also use a simple template with variadic argument to initialize, for example:

T[] Array(T, Elems...)(Elems elems){
    typeof(return) result;
    foreach(elem; elems)
        result ~= elem;
    return result;
}

void main(string args[]){
    auto a = Array!int(0,1,2,3,4,5,6);
    writeln(a);
}

which outputs:

[0, 1, 2, 3, 4, 5, 6]

Upvotes: 0

Andrey Penechko
Andrey Penechko

Reputation: 36

If you need simple solution, you can use the following code:

auto len = 10;
double[] arr = new double[len];
arr[] = value;

This code allocates new array of size len. Then all of its elements are initialized with value.

import std.stdio;

// Simple one.
double[] makeArray1(immutable uint len, immutable double value)
{
    double[] arr;
    arr.length = len;
    arr[] = value;
    return arr;
}

// Shorter variant of the first one.
double[] makeArray2(immutable uint len, immutable double value)
{
    double[] arr = new double[len];
    arr[] = value;
    return arr;
}

// In the case when appending is more convenient for you and you know the space you will need.
// You can reserve some array space and append to it,
// not wondering if any allocation will occur.
double[] makeArray3(immutable uint len, immutable double value)
{
    double[] arr;
    arr.reserve(len);
    foreach(_; 0..len)
        arr ~= value;
    return arr;
}

// Most efficient one. 
// Use it when you need to initialize a lot of elements right after allocation.
double[] makeArray4(immutable uint len, immutable double value)
{
    import std.array : uninitializedArray;
    double[] arr = uninitializedArray!(double[])(len);
    arr[] = value;
    return arr;
}

void main()
{
    uint x = 10;
    writeln(makeArray1(x, 5));
    writeln(makeArray2(x, 5));
    writeln(makeArray3(x, 5));
    writeln(makeArray4(x, 5));
}

Here you can try it online:

Upvotes: 2

Related Questions