Thread overview
Slices, appending to arbitrary position
Dec 30, 2013
Dfr
Dec 30, 2013
bearophile
Dec 30, 2013
Chris Cain
Dec 30, 2013
Dfr
Dec 30, 2013
H. S. Teoh
Dec 31, 2013
Regan Heath
Dec 31, 2013
bearophile
Dec 30, 2013
Jakob Ovrum
December 30, 2013
This simple example:

string[] a;
a[10] = "hello";

Gives me: core.exception.RangeError: Range violation

I know about this way:

string[] a;
a = new string[11];
a[10] = "hello";

But what if i need do this many times with the same array like this:

a[10] = "a";
...
a[1] = "b";
..
a[1000] = "c";

If i will call "a = new string[11]" all those many times, isn't this will be inefficient ? Also it will clear all previous contents of "a", which is not suitable.
December 30, 2013
Dfr:

> string[] a;
> a[10] = "hello";
>
> Gives me: core.exception.RangeError: Range violation

Because 'a' has length 0, so the position with index 11 doesn't exists in the array.

By the way, this is not an "appending", it's a (failed) assignment.


> I know about this way:
>
> string[] a;
> a = new string[11];
> a[10] = "hello";
>
> But what if i need do this many times with the same array like this:
>
> a[10] = "a";
> ...
> a[1] = "b";
> ..
> a[1000] = "c";
>
> If i will call "a = new string[11]" all those many times, isn't this will be inefficient ? Also it will clear all previous contents of "a", which is not suitable.

If you need to assign strings randomly then a good solution is to use an associative array, that is a quite different data structure:

string[int] aa;
aa[10] = "a";
aa[1] = "b";
aa[1000] = "c";


As alternative if you want a normal dynamic array, you can resize it:

string[int] a;
a.length = max(a.length, 10 + 1);
a[10] = "a";
a.length = max(a.length, 1 + 1);
a[1] = "b";
a.length = max(a.length, 1000 + 1);
a[1000] = "c";

Bye,
bearophile
December 30, 2013
On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:
> This simple example:
>
> string[] a;
> a[10] = "hello";
>
> Gives me: core.exception.RangeError: Range violation
>
> I know about this way:
>
> string[] a;
> a = new string[11];
> a[10] = "hello";
>
> But what if i need do this many times with the same array like this:
>
> a[10] = "a";
> ...
> a[1] = "b";
> ..
> a[1000] = "c";

Does it *need* to be an array for some reason?
If so, resize the array prior.

Something like:

    // index is the position you're changing
    // value is the value you're changing to
    if(a.length <= index) {
        a.length = index+1;
    }
    a[index] = value;

If you're just mapping integers to strings, then you're probably looking for an associative array:
http://dlang.org/hash-map.html

This is probably more like what you actually want:

    string[size_t] a;
    a[1] = "works fine";
    a[10] = "also works fine";



> isn't this will be inefficient ?

Yes. Resizing the array many times is very inefficient. Either use an associative array or know ahead of time what your array's length needs to be (or, at least, what it will "likely" need to be).
December 30, 2013
On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:
> This simple example:
>
> string[] a;
> a[10] = "hello";
>
> Gives me: core.exception.RangeError: Range violation
>
> I know about this way:
>
> string[] a;
> a = new string[11];
> a[10] = "hello";
>
> But what if i need do this many times with the same array like this:
>
> a[10] = "a";
> ...
> a[1] = "b";
> ..
> a[1000] = "c";
>
> If i will call "a = new string[11]" all those many times, isn't this will be inefficient ? Also it will clear all previous contents of "a", which is not suitable.

Arrays are contiguous chunks of memory. If you wanted to store "c" as the 1000th element in an array of strings, that array needs to have room for 1000 elements.

Perhaps what you want is an associative array:

----
string[uint] aa;
aa[10] = "a";
aa[1] = "b";
aa[1000] = "c";

writeln(aa[10], aa[1], aa[1000]);
----
December 30, 2013
Thank you for replies, i think here i can use assoc array, but sometimes it is not suitable because it is not preserve order.


> On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:
>> This simple example:
>>
>> string[] a;
>> a[10] = "hello";
>>
>> Gives me: core.exception.RangeError: Range violation
>>
>> I know about this way:
>>
>> string[] a;
>> a = new string[11];
>> a[10] = "hello";
>>
>> But what if i need do this many times with the same array like this:
>>
>> a[10] = "a";
>> ...
>> a[1] = "b";
>> ..
>> a[1000] = "c";
>
> Does it *need* to be an array for some reason?
> If so, resize the array prior.
>
> Something like:
>
>     // index is the position you're changing
>     // value is the value you're changing to
>     if(a.length <= index) {
>         a.length = index+1;
>     }
>     a[index] = value;
>
> If you're just mapping integers to strings, then you're probably looking for an associative array:
> http://dlang.org/hash-map.html
>
> This is probably more like what you actually want:
>
>     string[size_t] a;
>     a[1] = "works fine";
>     a[10] = "also works fine";
>
>
>
>> isn't this will be inefficient ?
>
> Yes. Resizing the array many times is very inefficient. Either use an associative array or know ahead of time what your array's length needs to be (or, at least, what it will "likely" need to be).
December 30, 2013
On Mon, Dec 30, 2013 at 06:40:24PM +0000, Dfr wrote:
> 
> Thank you for replies, i think here i can use assoc array, but sometimes it is not suitable because it is not preserve order.

Maybe you can use std.container.RedBlackTree instead? That will preserve order (but at the cost of asymptotically slower lookups / insertions).


T

-- 
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
December 31, 2013
On Mon, 30 Dec 2013 18:40:24 -0000, Dfr <deflexor@yandex.ru> wrote:

>
> Thank you for replies, i think here i can use assoc array, but sometimes it is not suitable because it is not preserve order.

What order do you want it in?  The index order?  If so, iterating over aa.keys.sort() will give you the keys in that order, and you can use that key to get the value aa[key] etc.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 31, 2013
Regan Heath:

> What order do you want it in?  The index order?  If so, iterating over aa.keys.sort() will give you the keys in that order, and you can use that key to get the value aa[key] etc.

I also suggested this:
http://d.puremagic.com/issues/show_bug.cgi?id=10733

Bye,
bearophile