www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Slices, appending to arbitrary position

reply "Dfr" <deflexor yandex.ru> writes:
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.
Dec 30 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Dec 30 2013
prev sibling next sibling parent reply "Chris Cain" <clcain uncg.edu> writes:
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).
Dec 30 2013
parent reply "Dfr" <deflexor yandex.ru> writes:
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).
Dec 30 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
Dec 30 2013
prev sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
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/
Dec 31 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Dec 31 2013
prev sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
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]); ----
Dec 30 2013