www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - multidimensional array setting/slicing?

reply "Saaa" <empty needmail.com> writes:
Is there a easy way to set/read a multidimensional slice of an array?

I'd like to do something like this... :)

int array[][];
array.length=100;
array[].length=200; :  Error: slice expression array[] is not a modifiable 
lvalue

int array2[][];
array2.length=4;
array2[].length=2;
array2=[[1,2,3,4],[5,6,7,8]];

array[10..10+array2.length][150..150+array2[].length]=array2; 
Jul 26 2008
parent reply Rakan Alhneiti <rakan.alhneiti nospam.gmail.com> writes:
Saaa wrote:
 Is there a easy way to set/read a multidimensional slice of an array?
 
 I'd like to do something like this... :)
 
 int array[][];
 array.length=100;
 array[].length=200; :  Error: slice expression array[] is not a modifiable 
 lvalue
 
 int array2[][];
 array2.length=4;
 array2[].length=2;
 array2=[[1,2,3,4],[5,6,7,8]];
 
 array[10..10+array2.length][150..150+array2[].length]=array2; 
 
 
I dont think you can do this in any programming language not just D. Initialization of inner arrays in multidimensional arrays is done most of the type using loops int array[][]; array.length = 100; for(int i = 0;i<array.length;i++) { array[i].length = 4; } as for slicing, i guess you will have to specify the starting and ending index. array2 = array1[0..5];
Jul 26 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Rakan Alhneiti" wrote
 Saaa wrote:
 Is there a easy way to set/read a multidimensional slice of an array?

 I'd like to do something like this... :)

 int array[][];
 array.length=100;
 array[].length=200; :  Error: slice expression array[] is not a 
 modifiable lvalue

 int array2[][];
 array2.length=4;
 array2[].length=2;
 array2=[[1,2,3,4],[5,6,7,8]];

 array[10..10+array2.length][150..150+array2[].length]=array2;
I dont think you can do this in any programming language not just D. Initialization of inner arrays in multidimensional arrays is done most of the type using loops int array[][]; array.length = 100; for(int i = 0;i<array.length;i++) { array[i].length = 4; }
Probably done easiest with a foreach loop: foreach(ref a; array) a.length = 4; The slicing is somthing that would have to be done using loops. you might not realize, but a multi-dimensional dynamic array is really an array of pointers, not one contiguous block of memory. So each sub-array points to a different memory space, and could have different lengths. a loop with foreach would look something like: foreach(i, ref a; array[10..10+array2.length]) a[] = array2[i]; Probably other ways to do it. -Steve
Jul 26 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Steven Schveighoffer" wrote
 "Rakan Alhneiti" wrote
 Saaa wrote:
 Is there a easy way to set/read a multidimensional slice of an array?

 I'd like to do something like this... :)

 int array[][];
 array.length=100;
 array[].length=200; :  Error: slice expression array[] is not a 
 modifiable lvalue

 int array2[][];
 array2.length=4;
 array2[].length=2;
 array2=[[1,2,3,4],[5,6,7,8]];

 array[10..10+array2.length][150..150+array2[].length]=array2;
I dont think you can do this in any programming language not just D. Initialization of inner arrays in multidimensional arrays is done most of the type using loops int array[][]; array.length = 100; for(int i = 0;i<array.length;i++) { array[i].length = 4; }
Probably done easiest with a foreach loop: foreach(ref a; array) a.length = 4; The slicing is somthing that would have to be done using loops. you might not realize, but a multi-dimensional dynamic array is really an array of pointers, not one contiguous block of memory. So each sub-array points to a different memory space, and could have different lengths. a loop with foreach would look something like: foreach(i, ref a; array[10..10+array2.length]) a[] = array2[i];
err.. that should have been a[150..150+array2[i].length] = array2[i]; -Steve
Jul 26 2008
parent reply "Saaa" <empty needmail.com> writes:
Thanks, the code now looks like this (and works :)

 int array[][];
 array.length=10;
 foreach(ref a; array)
  a.length = 5;

 int array2[][];
 array2.length=2;
 foreach(ref a; array)
  a.length = 6;

array2=[[1,2,3,4],[5,6,7,8]];

foreach(i, ref a; array[2..2+array2.length])
 a[1..1+array2[i].length] = array2[i];

 writefln(array2);
 writefln(array);

[[1,2,3,4],[5,6,7,8]]
[[0,0,0,0,0,0],[0,0,0,0,0,0],[0,1,2,3,4,0],[0,5,6,7,8,0],[0,0,0,0,0,0],
[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]
--------------------------
//And for 3D:

 int array[][][];
 array.length=6;
 foreach(ref a; array)
 {
  a.length = 6;
  foreach(ref b; a)
   b.length = 6;
 }

 int array2[][][];
 array2.length=2;
 foreach(ref a; array2)
 {
  a.length = 2;
  foreach(ref b; a)
   b.length = 2;
 }


 array2=[[[1,2],[5,6]],[[9,9],[8,7]]];

 foreach(i, ref a; array[2..2+array2.length])
 foreach(ii, ref b; a[2..2+array2[0].length])
  b[1..1+array2[ii].length] = array2[i][ii];

 writefln(array2);
 writefln(array);
--------------------------
... erm I barely follow it myself :/

I think array can be static and maybe array2 will be as well and I'll 
manually keep the x,y and z sizes and do normal for-loops over them.
Jul 27 2008
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Saaa" wrote
 Thanks, the code now looks like this (and works :)

 int array[][];
 array.length=10;
 foreach(ref a; array)
  a.length = 5;

 int array2[][];
You can comment out these lines: /*
 array2.length=2;
 foreach(ref a; array)
  a.length = 6;
*/
 array2=[[1,2,3,4],[5,6,7,8]];
could be: auto array2=[[1,2,3,4],[5,6,7,8]]; and get rid of the array2 declaration above. At this point, you have thrown away all your work you did to set the lengths in array2 :) Note that setting array2 this way just changes the array to point to the array literal, it doesn't copy data from the literal.
 foreach(i, ref a; array[2..2+array2.length])
 a[1..1+array2[i].length] = array2[i];

 writefln(array2);
 writefln(array);

 [[1,2,3,4],[5,6,7,8]]
 [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,1,2,3,4,0],[0,5,6,7,8,0],[0,0,0,0,0,0],
 [0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]
 --------------------------
 //And for 3D:

 int array[][][];
 array.length=6;
 foreach(ref a; array)
 {
  a.length = 6;
  foreach(ref b; a)
   b.length = 6;
 }

 int array2[][][];
ditto here: /*
 array2.length=2;
 foreach(ref a; array2)
 {
  a.length = 2;
  foreach(ref b; a)
   b.length = 2;
 }
*/
 array2=[[[1,2],[5,6]],[[9,9],[8,7]]];
could be: auto array2=[[[1,2],[5,6]],[[9,9],[8,7]]];
 foreach(i, ref a; array[2..2+array2.length])
 foreach(ii, ref b; a[2..2+array2[0].length])
  b[1..1+array2[ii].length] = array2[i][ii];

 writefln(array2);
 writefln(array);
 --------------------------
 ... erm I barely follow it myself :/
Yeah, it's not really that readable :) Perhaps encapsulating it into a function would be more readable.
 I think array can be static and maybe array2 will be as well and I'll 
 manually keep the x,y and z sizes and do normal for-loops over them.
static arrays are different than dynamic arrays, in that they are contiguous memory :) But I think you will still need to set the data in the same way. -Steve
Jul 28 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Saaa Wrote:
 ... erm I barely follow it myself :/
There are ways to shorten your code a little, and/or to make it a bit more readable. You have to learn still where to put spaces too.
  int array[][];
  array.length=10;
  foreach(ref a; array)
   a.length = 5;
There's this syntax too, if you remember the order of the sizes: auto array = new int[][][](n1, n2, n3); foreach(ref a; array) => foreach (ref a; array)
 a[1..1+array2[i].length] = array2[i];
=>
 a[1 .. 1+array2[i].length] = array2[i];
array2.length=2; => array2.length = 2; In some situations you can use $ instead of length (but not in the code you have shown, I think). And you can write yourself a slice(...) function able to perform your complex slices reducing syntax clutter (but it doesn't support the .. operator, sadly, as in the .../: of python). Note that this: auto a = [[1, 2], [3, 4]]; Isn't the same thing as: int[][] a = [[1, 2], [3, 4]]; If you use auto the compiler chooses to use a static array. Bye, bearophile
Jul 28 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:g6kn24$77v$1 digitalmars.com...

 You have to learn still where to put spaces too.
 foreach(ref a; array)
 =>
 foreach (ref a; array)

 a[1..1+array2[i].length] = array2[i];
=>
 a[1 .. 1+array2[i].length] = array2[i];
array2.length=2; => array2.length = 2;
Don't you think you're being a bit pedantic? Whitespace is optional and everyone has their own preferences.
Jul 28 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Rakan Alhneiti:
 I dont think you can do this in any programming language not just D.
I think in NumPy you can do similar things (and maybe in matlab too). Bye, bearophile
Jul 26 2008
parent BCS <ao pathlink.com> writes:
Reply to bearophile,

 Rakan Alhneiti:
 
 I dont think you can do this in any programming language not just D.
 
I think in NumPy you can do similar things (and maybe in matlab too).
yes in matlab.
Jul 27 2008