Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 07, 2020 What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
I read all the docs but I'm not toally sure. Is it that [x][y] is a 2D array-index, where as [x,y] is a slice?
But the example in docs for opIndexAssign uses the [x,y] syntax, which is confusing:
```
struct A
{
int opIndexAssign(int value, size_t i1, size_t i2);
}
void test()
{
A a;
a[i,3] = 7; // same as a.opIndexAssign(7,i,3);
}
```
And what is the difference between opIndexAssign and opIndexOpAssign?
Background: I have a class with a 2D array of some other class objects as memember and want to be able to use it as LHS and RHS.
--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
|
January 07, 2020 Re: What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Tuesday, 7 January 2020 at 17:38:59 UTC, Robert M. Münch wrote: > I read all the docs but I'm not toally sure. Is it that [x][y] is a 2D array-index, where as [x,y] is a slice? So [x][y] indexes an array of arrays. [x,y] indexes a single array that has two dimensions. This can be kinda confusing because we often think of int[4][4] as being a 2d array, but the D language actually technically sees that as an array of arrays. So it is indexed with [x][y]. There is no built in multi-dimensional array, it is only syntax provided for library types to implement with the opIndexAssign overloads. > And what is the difference between opIndexAssign and opIndexOpAssign? foo[5] = x; // opIndexAssign foo[4] += x; // opIndexOpAssign So the operator there like += or -= or *= etc become opAssign, whereas plain = is just plain Assign. |
January 07, 2020 Re: What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe Attachments:
| On 2020-01-07 17:42:48 +0000, Adam D. Ruppe said: > So [x][y] indexes an array of arrays. Yes, that's what I understand. And both can be dynamic, so that I can have a "flattering" layout where not all arrays have the same length. > [x,y] indexes a single array that has two dimensions. Does this fix the dimension sizes? So I can't add a "row" or "column" at runtime? What are the difference use-cases for these two? For example, I'm doing a grid widget but want to add/remove rows/columns. Can this only be done with a array-of-array? Is the memory continuous in the [x,y] case, whereas in the [x][y] this is not necessarily the case? > This can be kinda confusing because we often think of > > int[4][4] > > as being a 2d array, but the D language actually technically sees that as an array of arrays. So it is indexed with [x][y]. Yes, it's confusing as I don't understand the [x,y] case :-) > There is no built in multi-dimensional array, it is only syntax provided for library types to implement with the opIndexAssign overloads. I don't get that sentence. Above you write "a single array that has two dimensions" which IMO is exactly a multi-dimensional array. > So the operator there like += or -= or *= etc become opAssign, whereas plain = is just plain Assign. Got it. Thanks. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
January 07, 2020 Re: What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Tue, Jan 07, 2020 at 06:38:59PM +0100, Robert M. Münch via Digitalmars-d-learn wrote: > I read all the docs but I'm not toally sure. Is it that [x][y] is a 2D array-index, where as [x,y] is a slice? arr[x][y] is indexing an array of arrays. arr[x,y] is indexing an actual multi-dimensional array. The language does not have a built-in implementation of multi-dimensional arrays, so the only time you can use the arr[x,y] syntax is when you write your own type that overloads opIndex. Here's a quick-n-dirty example: struct Array2D(T) { private T[] impl; private int width, height; this(int w, int h) { width = w; height = h; impl.length = width*height; } // Notice that opIndex takes *two* parameters, this is // what allows us to use arr[x,y] syntax. ref T opIndex(int i, int j) { return impl[i + width*j]; } } auto arr = Array2D!int(3, 3); arr[0, 0] = 1; arr[1, 1] = 2; ... In the same vein you can write a type that declares opIndex with 3 or more parameters, then you can get higher-dimensional indexing. If you implement opDollar, then you can also use $ in your indexing, e.g.: struct MyArray(T) { private int width, height; ... int opSlice(size_t dim)() { static if (dim == 0) return width; else return height; } } MyArray!int arr; arr[$-2, $-3] = 1; You can also implement slicing syntax like: arr[2 .. $, 0 .. 3] To do this, you need to overload .opSlice with two indices, returning some object defining a range (i.e., encapsulates "2..$" or "0..3"), say we call it IdxRange. Then overload opIndex to understand arguments of type IdxRange. For example: struct IdxRange { int start, end; } struct MyArray(T) { ... IdxRange opSlice(int start, int end) { return IdxRange(start,end); } T opIndex(IdxRange colRange, IdxRange rowRange) { ... // return subarray here } } Basically, this: arr[2 .. $, 0 .. 3] gets translated to this: arr.opIndex(arr.opSlice(2, arr.opDollar!0), arr.opSlice(0, 3)); It's up to you how to implement all of this, of course. The language itself doesn't ship a built-in type that implements this, but it does provide the scaffolding for you to build a custom multi-dimensional array type. [...] > And what is the difference between opIndexAssign and opIndexOpAssign? [...] opIndexAssign is for implementing operations of the form: arr[x, y] = z; opIndexOpAssign is for implementing operations of the form: arr[x, y] += z; arr[x, y] *= z; // etc. In the previous examples I had opIndex return ref, for simplicity, so you could just assign to the array element via the ref. But if your array implementation differentiates between looking up an element vs. assigning to an element, then you'll want to provide your own implementation of opIndexAssign and/or opIndexOpAssign: struct MyArray(T) { ... void opIndexAssign(T value, int x, int y) { T* elem = lookupElement(x, y); *elem = value; } void opIndexOpAssign(string op)(T value, int x, int y) { T* elem = lookupElement(x, y); mixin("*elem "~op~"= value;"); } } T -- Try to keep an open mind, but not so open your brain falls out. -- theboz |
January 08, 2020 Re: What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2020-01-07 19:06:09 +0000, H. S. Teoh said: > It's up to you how to implement all of this, of course. The language > itself doesn't ship a built-in type that implements this, but it does > provide the scaffolding for you to build a custom multi-dimensional > array type. Hi, thanks for your extensive answer! Helped a lot... And the above paraghraph brings it to the core. How can this be added to the D docs? I think adding such clear "this is the idea how you should use it" intros would help a lot to see the world from a d-ish perspective. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
January 08, 2020 Re: What is the difference between a[x][y] and a[x,y]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Wed, Jan 08, 2020 at 09:09:23AM +0100, Robert M. Münch via Digitalmars-d-learn wrote: > On 2020-01-07 19:06:09 +0000, H. S. Teoh said: > > > It's up to you how to implement all of this, of course. The language itself doesn't ship a built-in type that implements this, but it does provide the scaffolding for you to build a custom multi-dimensional array type. > > Hi, thanks for your extensive answer! Helped a lot... > > And the above paraghraph brings it to the core. > > How can this be added to the D docs? I think adding such clear "this is the idea how you should use it" intros would help a lot to see the world from a d-ish perspective. [...] File a bug against dlang.org, and maybe when I get some free time I'll try to write something up. T -- Designer clothes: how to cover less by paying more. |
Copyright © 1999-2021 by the D Language Foundation