Thread overview
multidimensional array setting/slicing?
Jul 26, 2008
Saaa
Jul 26, 2008
Rakan Alhneiti
Jul 28, 2008
Saaa
Jul 28, 2008
bearophile
Jul 26, 2008
bearophile
Jul 27, 2008
BCS
July 26, 2008
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;


July 26, 2008
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];
July 26, 2008
"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



July 26, 2008
"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


July 26, 2008
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
July 27, 2008
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.


July 28, 2008
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.


July 28, 2008
"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


July 28, 2008
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
July 28, 2008
"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.