Associative Array with double[][]

bauss jj_1337 at live.dk
Thu Jul 22 12:10:40 UTC 2021


On Thursday, 22 July 2021 at 03:13:14 UTC, seany wrote:
> I have a perimeter of a shape, given by a `double [][]` . I 
> want to keep the lengths of various diagonals in another 
> associative array.
>
> So,
>
>     /// define some associative array to keep track of 
> diagonals here..
>
>     auto perimeter = new double[][] (0,0);
>
>     /// --- fill up perimeter here ---
>
>     for(int i = 0; i < perimeter.length; i++) {
>       for ( int j = 0; j < perimeter.length; j++) {
>
>       //// fill up the associative array here
>
>       }
>     }
>
>
> So, I would like to do this:
>
>     double[ double[][]] diagonalLengths;
>     auto perimeter = new double[][] (0,0);
>
>     /// --- fill up perimeter here ---
>
>     for(int i = 0; i < perimeter.length; i++) {
>       for ( int j = 0; j < perimeter.length; j++) {
>
>       auto diag_point_i = perimeter[i];
>       auto diag_point_j = perimeter[j];
>
>       diagonalLengths [ [diag_point_i, diag_point_j]] = 
> calculate_length (i,j);
>
>       }
>     }
>
>
> This is necessary, as further processing will change the 
> indices of the points in the perimeter. I can't therefore use ` 
> diagonalLengths [ [i,j]] = calculate_length (i,j);`
>
> However, trying to do this is resulting to :
>
> `test.d(29): Error: associative arrays can only be assigned 
> values with immutable keys, not `double[][]`
>
> What are my options now?  Do I have to convert the array which 
> i plan to use as a key to a struct and define opEquals and 
> toHash?
>
> Are there automatic hashing mechanisms for this?
>
> If there are multiple possibilities, what is the fastest in 
> terms of memory? Thank you.

A possible but not that beautiful solution would be using string 
keys.

And then using UFC to make a "toKey" function that takes your 
double[][] as parameter.

To do this the first change would be your associative array has 
to be changed to:

```d
double[string] diagonalLengths;
```

The next change would be adding the "toKey" function, something 
like this should work:

```d
string asKey(double[][] d)
{
     import std.algorithm : map;
     import std.array : array, join;
     import std.conv : to;

     return d.map!(e => e.map!(i => 
i.to!string).join("_")).array.join(":");
}
```

The last change would be accessing the associative array you 
simply do it like this:

```d
diagonalLengths [ [diag_point_i, diag_point_j].asKey]
```

As you can see the only change in your logic is just adding the 
.asKey function call.

It's of course not gonna be fast or anything but it's functional.


More information about the Digitalmars-d-learn mailing list