Re: Assigning to slice of array

2018-03-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/1/18 5:59 PM, ag0aep6g wrote:

On 03/01/2018 11:43 PM, Jamie wrote:

So if I do
 arr[0 .. 1][0] = 3;
shouldn't this return
 [[3, 0, 0], [0, 0, 0]] ? Because I'm taking the slice arr[0 .. 
1], or arr[0], which is the first [0, 0, 0]?


arr[0 .. 1] is not the same as arr[0].

arr[0 .. 1] is not the first element of arr; it's an array that contains 
the first element of arr. It's not [0, 0, 0]; it's [[0, 0, 0]]. It's not 
an int[]; it's an int[][].


Minor correction, it's actually an int[3][].

Try arr[1 .. 2][0] = 3; It will affect the second static array.

I understand what you really want is the first element of each static 
array. There is no supported syntax for arrays to slice like that. This 
is where ndslice comes in.


But if it *were* supported, it would look like this instead (I think 
this is how ndslice would work, but I've never used it):


arr[0 .. 2, 0] = 3;

The thing I think you are missing is that the expression stops at the 
closing bracket.


In other words arr[0 .. 2][0] is really (arr[0 .. 2])[0].

arr[0 .. 2] is a slice of the original array, which happens to be the 
entire array. So it really doesn't get you anything.


One final note. If you don't want to use array assignment operators, and 
don't mind using ranges, you can do what you want this way:


https://run.dlang.io/is/AdikEE

-Steve


Re: Assigning to slice of array

2018-03-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, March 01, 2018 23:51:37 Jamie via Digitalmars-d-learn wrote:
> On a similar not, is there an accepted way to assign across
> arrays? As Steve mentioned, cross-slicing isn't supported, so is
> the best way to iterate through the array and assign as necessary?

That's what you would have to do. You're basically dealing with stuff like
int*** except that it also has its length with it and wraps it in a nicer
way, and so each of these buffers that you're dealing with are essentially
unrelated. They just have a common root. Even if there were some sort of
high level operation that did something along the lines of what you're
looking for, it would pretty much have to lower to something along the lines
of what you'd be doing to solve the problem on your own. It's not like these
are these are buffers which are somehow squares or cubes in memory such that
they you could slice along a different dimension. They're still just linear
buffers of memory.

- Jonathan M Davis



Re: Assigning to slice of array

2018-03-01 Thread Jamie via Digitalmars-d-learn

On Thursday, 1 March 2018 at 23:17:11 UTC, Jonathan M Davis wrote:

So, something like

auto arr = new int[][][](3, 2, 1);
arr.length = 4;
arr[0].length = 5;
arr[0][0].length = 6;

is legal, but something like


Thanks Jonathan, this is exactly what I was looking for. I was 
getting confused with not being able to resize because I was 
looking at int[] arrays and I guess the way I was defining them 
caused them both to be dynamic (when I thought one was static).


On a similar not, is there an accepted way to assign across 
arrays? As Steve mentioned, cross-slicing isn't supported, so is 
the best way to iterate through the array and assign as necessary?

Thanks, Jamie







Re: Assigning to slice of array

2018-03-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, March 01, 2018 22:57:16 Jamie via Digitalmars-d-learn wrote:
> On Thursday, 1 March 2018 at 21:34:41 UTC, Jonathan M Davis wrote:
> > Don't put the indices within the brackets. What you want is
> >
> > auto arr = new int[][][](3, 2, 1);
>
> Okay thanks, but I don't understand what is the issue with having
> static arrays there instead? My functionality didn't change when
> I replaced the single line with your line?
>
> And I couldn't resize either of them with array.length, which is
> also something I would like.
> Thanks

static arrays have a fixed size, so you can't resize them with any operation
- including setting their length. Static arrays are value types, so when
they're copied, the whole thing is copied, whereas with a dynamic array is
just a pointer and a length, so copying it just slices the dynamic array to
give you another dynamic array. It's just copying the pointer and the
length. A dynamic array is effectively

struct DynamicArray(T)
{
size_t length;
T* ptr;
}

whereas a static array is an actual buffer that sits wherever it's declared
(on the stack if it's a local variable).

So, something like

auto arr = new int[][][](3, 2, 1);
arr.length = 4;
arr[0].length = 5;
arr[0][0].length = 6;

is legal, but something like

auto arr = new int[3][2][1];
arr.length = 4; // this one is still legal, since it's a dynamic array
arr[0].length = 5;
arr[0][0].length = 6;

is not legal.

- Jonathan M Davis



Re: Assigning to slice of array

2018-03-01 Thread Jamie via Digitalmars-d-learn

On Thursday, 1 March 2018 at 21:34:41 UTC, Jonathan M Davis wrote:

Don't put the indices within the brackets. What you want is

auto arr = new int[][][](3, 2, 1);


Okay thanks, but I don't understand what is the issue with having 
static arrays there instead? My functionality didn't change when 
I replaced the single line with your line?


And I couldn't resize either of them with array.length, which is 
also something I would like.

Thanks




Re: Assigning to slice of array

2018-03-01 Thread ag0aep6g via Digitalmars-d-learn

On 03/01/2018 11:43 PM, Jamie wrote:

So if I do
     arr[0 .. 1][0] = 3;
shouldn't this return
     [[3, 0, 0], [0, 0, 0]] ? Because I'm taking the slice arr[0 .. 1], 
or arr[0], which is the first [0, 0, 0]?


arr[0 .. 1] is not the same as arr[0].

arr[0 .. 1] is not the first element of arr; it's an array that contains 
the first element of arr. It's not [0, 0, 0]; it's [[0, 0, 0]]. It's not 
an int[]; it's an int[][].


Then assigning the first 
element to 3?

instead it returns
     [[3, 3, 3], [0, 0, 0]]


Since arr[0 .. 1] is [[0, 0, 0]], arr[0 .. 1][0] is [0, 0, 0]. Assigning 
3 to that means assigning to all of its values. And so you get [3, 3, 3].


Re: Assigning to slice of array

2018-03-01 Thread Jamie via Digitalmars-d-learn
On Thursday, 1 March 2018 at 21:31:49 UTC, Steven Schveighoffer 
wrote:
No, I think you did int[3][2], if you got that output. 
Otherwise it would have been:


[[[0,0,0],[0,0,0]]]


Yes apologies that was there from a previous attempt, you are 
correct.


Well, that's because that type of slicing isn't supported 
directly. You can't slice an array cross-wise like that.


You may be interested in ndslice inside mir: 
http://docs.algorithm.dlang.io/latest/mir_ndslice.html


Thanks I've just had a quick read and this looks promising for 
what I want (similar functionality to numpy), but I also want to 
understand arrays.



when I try
     arr[0 .. 2][0] = 3;   // which I think is equivalent to 
arr[0][0]


Consider the array:

int[] x = new int[2];

Now, what would the slice x[0 .. 2] be? That's right, the same 
as x.


So when you slice arr[0 .. 2], it's basically the same as arr 
(as arr has 2 elements).


So arr[0 .. 2][0] is equivalent to arr[0].


So if I do
arr[0 .. 1][0] = 3;
shouldn't this return
[[3, 0, 0], [0, 0, 0]] ? Because I'm taking the slice arr[0 
.. 1], or arr[0], which is the first [0, 0, 0]? Then assigning 
the first element to 3?

instead it returns
[[3, 3, 3], [0, 0, 0]]

One thing that is interesting is that you assigned 3 to an 
array, and it wrote it to all the elements. I did not know you 
could do that with static arrays without doing a proper slice 
assign. But it does compile (I learn something new every day).


-Steve

Well I'm learning a lot today :)




Re: Assigning to slice of array

2018-03-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/1/18 4:16 PM, Jamie wrote:
I'm trying to understand arrays and have read a lot of the information 
about them on this forum. I think I understand that they are set-up like 
Type[], so that int[][] actually means an array of int[].


I create an array as per the following:
     auto arr = new int[3][2][1];
which produces:
     [[0, 0, 0], [0, 0, 0]]


No, I think you did int[3][2], if you got that output. Otherwise it 
would have been:


[[[0,0,0],[0,0,0]]]

Looking at the rest of your code, I think it wouldn't work if you had 
done the line above.


(for each of the following assignments, assume that the array is set 
back to zeros)


and I can change the 2nd element of the 1st array using:
     arr[0][1] = 4;
which produces:
     [[0, 4, 0], [0, 0, 0]]

and I can change the entire 1st array using:
     arr[0][0 .. 3] = 5;
which produces:
     [[5, 5, 5], [0, 0, 0,]]


Yes, all correct.



however when I try and change elements across arrays rather than within 
arrays my understanding breaks down..


Well, that's because that type of slicing isn't supported directly. You 
can't slice an array cross-wise like that.


You may be interested in ndslice inside mir: 
http://docs.algorithm.dlang.io/latest/mir_ndslice.html



when I try
     arr[0 .. 2][0] = 3;   // which I think is equivalent to arr[0][0] 


Consider the array:

int[] x = new int[2];

Now, what would the slice x[0 .. 2] be? That's right, the same as x.

So when you slice arr[0 .. 2], it's basically the same as arr (as arr 
has 2 elements).


So arr[0 .. 2][0] is equivalent to arr[0].

One thing that is interesting is that you assigned 3 to an array, and it 
wrote it to all the elements. I did not know you could do that with 
static arrays without doing a proper slice assign. But it does compile 
(I learn something new every day).


-Steve


Re: Assigning to slice of array

2018-03-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, March 01, 2018 21:16:54 Jamie via Digitalmars-d-learn wrote:
> I'm trying to understand arrays and have read a lot of the
> information about them on this forum. I think I understand that
> they are set-up like Type[], so that int[][] actually means an
> array of int[].
>
> I create an array as per the following:
>  auto arr = new int[3][2][1];
> which produces:

Don't put the indices within the brackets. What you want is

auto arr = new int[][][](3, 2, 1);

With a new expression, unless you only have one dimension, you end up with
dynamic arrays of static arrays. e.g. if you use what I wrote there with

pragma(msg, typeof(arr).stringof);

it prints

int[][][]

whereas with what you wrote, you get

int[3][2][]

which is a dynamic array of a static array of length 2 of static arrays of
int of length 3 rather than a dynamic array of a dynamic array of a dynamic
array of ints. Unfortunately,

auto arr = new int[5];

and

auto arr = new int[](5);

are equivalent, so dealing with just single dimension arrays does not
prepare you properly for dealing with multi-dimensional arrays. Arguably, it
would have been better to just force using the parens, though that would
make the most common case more verbose, so it's debatable.

- Jonathan M Davis