Is it somehow possible to use a struct as a [multidimensional] array index:
struct indexedPair
{
size_t x, y;
}
bool isMapPassable[100][100];
auto p = indexedPair(50, 50);
if(isMapPassable[p]) return true;
Probably not, but I'm curious.
Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 10, 2022 a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Is it somehow possible to use a struct as a [multidimensional] array index:
Probably not, but I'm curious. |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On 6/10/22 01:08, Chris Katko wrote: > Is it somehow possible to use a struct as a [multidimensional] array index: You can define an opIndex that takes any index type if the array is defined by you: import std.stdio; import std.format; struct indexedPair { size_t x, y; } struct MyArray { bool[3][3] elements; ref opIndex(indexedPair i) { return elements[i.y][i.x]; } // void toString(scope void delegate(in char[]) sink) const { // import std.algorithm; // sink.formattedWrite!"%-(%-(%s %)\n%)"( // elements[].map!(row => row[].map!(column => column ? 'T' : 'f'))); // } } void main() { auto arr = MyArray(); auto p = indexedPair(1, 1); arr[p] = true; writeln(arr); } I played with that toString function but for some reason it prints all Ts. (?) Ali |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Fri, Jun 10, 2022 at 08:08:45AM +0000, Chris Katko via Digitalmars-d-learn wrote: > Is it somehow possible to use a struct as a [multidimensional] array index: > > ````D > > struct indexedPair > { > size_t x, y; > } > > bool isMapPassable[100][100]; > auto p = indexedPair(50, 50); > > if(isMapPassable[p]) return true; > > ```` > > Probably not, but I'm curious. See: https://dlang.org/spec/operatoroverloading.html#array-ops T -- It won't be covered in the book. The source code has to be useful for something, after all. -- Larry Wall |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 6/10/22 07:38, Ali Çehreli wrote: > I played with that toString function but for some reason it prints all > Ts. (?) Fixed it by changing one of the lambdas to take by reference: void toString(scope void delegate(in char[]) sink) const { import std.algorithm; sink.formattedWrite!"%-(%-(%s %)\n%)"( elements[].map!((ref row) => row[].map!(column => column ? 'T' : 'f'))); // ^^^ } I still don't understand the reason though. The rows would be copied without ref but should retain their type as bool[3], a static array. (?) Ali |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Friday, 10 June 2022 at 08:08:45 UTC, Chris Katko wrote: >Is it somehow possible to use a struct as a [multidimensional] array index:
Probably not, but I'm curious. AFAIK no. To give you an idea of the situation :
One thing you could do however is make the array accept a multidimensional argument through operator overloading(opIndex) if it is the only array from a struct, but that gets unviable when you have multiple arrays that would benefit from it. To summarize, there does not appear to be an easy solution that has no drawbacks. I'd recommend saving yourself the trouble of array of arrays(of arrays?) and using a single array of length x*y with a function to index into it |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 6/10/22 08:01, Ali Çehreli wrote: > I still don't understand the reason though. The rows would be copied > without ref but should retain their type as bool[3], a static array. (?) Ok, now I see the very sinister problem: It is a disaster to combine static array lambda parameters with the laziness of range algorithms. The following program prints garbage because by the time writeln prints the elements, those elements are on invalid places on the stack: import std; void main() { int[3][3] arr; writeln( arr[] // Have to slice .map!(row => row[] // Have to slice .map!(element => element)) ); } The output is garbage element values. The programmer must take the parameter of the outer map by reference so that the elements are referring to actual elements in 'arr': .map!((ref row) => /* ... */ I don't think I realized this issue before, which may be caught by various combinations of safety compiler switches, which I haven't tried yet. Ali |
June 10, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to z | On 6/10/22 08:13, z wrote: > arrays of arrays has different order for declaration and addressing, > and declaring array of arrays has different order depending on how you > declare it and wether it's static or dynamic array, *oof*) > > To give you an idea of the situation : > ```D > int[3][1] a;//one array of 3 int > writeln(a[0][2]);//first "column", third "row" > ``` I've written about this multiple times in the past but D's way is consistent for me. That must be because I always found C's syntax to be very illogical on this. To me, C's problem starts with putting the variable name in the middle: // C code: int a[1][3]; // Why? So, first, D moves the variable to its consistent place: after the type: int i; int[N] arr; Both of those are in the form of "type and then name". Good... And then, here is the consistency with arrays: "type and then square brackets". int[] dynamicArray; int[N] staticArray; So, here is where you and I differ: int[3][1] arr; // Ali likes int[1][3] arr; // z wants I like it because it is consistently "type and then square brackets". (It so happens that the type of each element is int[N] in this case.) If it were the other way, than array syntax would be inconsistent with itself. :) Or, we would have to accept that it is inside-out like in C. But of course I understand how it is seen as consistent from C's point of view. :) And this is consistent with static vs dynamic as well because again it's "type and then square brackets": int[1][] a; // A dynamic array of int[1] int[][3] b; // A static array of 3 int[]s Ali |
June 11, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 10 June 2022 at 17:26:48 UTC, Ali Çehreli wrote:
> On 6/10/22 08:13, z wrote:
>
> > arrays of arrays has different order for declaration and
> addressing,
> > and declaring array of arrays has different order depending
> on how you
> > declare it and wether it's static or dynamic array, *oof*)
> >
> > To give you an idea of the situation :
> > ```D
> > int[3][1] a;//one array of 3 int
> > writeln(a[0][2]);//first "column", third "row"
> > ```
>
> I've written about this multiple times in the past but D's way is consistent for me. That must be because I always found C's syntax to be very illogical on this. To me, C's problem starts with putting the variable name in the middle:
>
> // C code:
> int a[1][3]; // Why?
>
> So, first, D moves the variable to its consistent place: after the type:
>
> int i;
> int[N] arr;
>
> Both of those are in the form of "type and then name". Good...
>
> And then, here is the consistency with arrays: "type and then square brackets".
>
> int[] dynamicArray;
> int[N] staticArray;
>
> So, here is where you and I differ:
>
> int[3][1] arr; // Ali likes
> int[1][3] arr; // z wants
>
> I like it because it is consistently "type and then square brackets". (It so happens that the type of each element is int[N] in this case.) If it were the other way, than array syntax would be inconsistent with itself. :) Or, we would have to accept that it is inside-out like in C.
>
> But of course I understand how it is seen as consistent from C's point of view. :)
>
> And this is consistent with static vs dynamic as well because again it's "type and then square brackets":
>
> int[1][] a; // A dynamic array of int[1]
> int[][3] b; // A static array of 3 int[]s
>
> Ali
This is an interesting discussion. I had noticed multi-dim arrays seemed backwards but I assumed I was doing something wrong and had other thing to worry about. I had no idea it was DIFFERENT for static vs dynamic arrays? That's horrifying!
Also you reminded me of a possible D bug that I ran into. I had classes that had circular dependencies. One had to know about the other, and vice-versa. And I had derived classes. But somehow, they would explode. I would send one reference to the others constructor to 'link' them together, but the reference would be NULL. But if I accessed the exact same variable through a global reference, it worked fine.
I tried ripping the affected code into a new file but the bug wasn't replicated. Even if I matched the compiler/linker options. It was super frustrating.
|
June 11, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Saturday, 11 June 2022 at 03:56:32 UTC, Chris Katko wrote: >On Friday, 10 June 2022 at 17:26:48 UTC, Ali Çehreli wrote: >On 6/10/22 08:13, z wrote: >arrays of arrays has different order for declaration and To give you an idea of the situation :
I've written about this multiple times in the past but D's way is consistent for me. That must be because I always found C's syntax to be very illogical on this. To me, C's problem starts with putting the variable name in the middle: // C code: So, first, D moves the variable to its consistent place: after the type: int i; Both of those are in the form of "type and then name". Good... And then, here is the consistency with arrays: "type and then square brackets". int[] dynamicArray; So, here is where you and I differ: int[3][1] arr; // Ali likes I like it because it is consistently "type and then square brackets". (It so happens that the type of each element is int[N] in this case.) If it were the other way, than array syntax would be inconsistent with itself. :) Or, we would have to accept that it is inside-out like in C. But of course I understand how it is seen as consistent from C's point of view. :) And this is consistent with static vs dynamic as well because again it's "type and then square brackets": int[1][] a; // A dynamic array of int[1] Ali This is an interesting discussion. I had noticed multi-dim arrays seemed backwards but I assumed I was doing something wrong and had other thing to worry about. I had no idea it was DIFFERENT for static vs dynamic arrays? That's horrifying! Also you reminded me of a possible D bug that I ran into. I had classes that had circular dependencies. One had to know about the other, and vice-versa. And I had derived classes. But somehow, they would explode. I would send one reference to the others constructor to 'link' them together, but the reference would be NULL. But if I accessed the exact same variable through a global reference, it worked fine. I tried ripping the affected code into a new file but the bug wasn't replicated. Even if I matched the compiler/linker options. It was super frustrating. I rechecked and it should be The dillema is that alone, the orders are sound byproducts of the language rules, it's when they are put in relation to each other that it can become weird. The bug could also be one of those implementation-specific bugs that are seemingly impossible to reproduce minimally because they require unknown very specific conditions to occur. Self and inter referencing appears unstable whenever it is not in the module/global scope. |
June 11, 2022 Re: a struct as an multidimensional array index | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 10 June 2022 at 17:26:48 UTC, Ali Çehreli wrote: >I've written about this multiple times in the past but D's way is consistent for me. That must be because I always found C's syntax to be very illogical on this. [...] I think so too... I think D is very consistent with our feelings. That is, the order in memory is in the form of rows x columns. But yes, in reverse(column x row) when you set it up statically. This sample code working on pointers can be a proof:
SDB@79 |