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.