Search code examples
arraysd

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?


Solution

  • 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: