Thread overview
Associative Array with double[][]
3 days ago
seany
3 days ago
frame
3 days ago
frame
3 days ago
bauss
3 days ago

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.

3 days ago

On Thursday, 22 July 2021 at 03:13:14 UTC, seany wrote:

>

If there are multiple possibilities, what is the fastest in terms of memory? Thank you.

I believe the fastest way (as seen from your loop) would be using pointer arithmetric and using void* keys for diagonalLengths and an index function that is able to pick the void* key/address from the given double coordinates.

You may also consider using a binary tree data structure instead of AA.

3 days ago

On Thursday, 22 July 2021 at 04:46:13 UTC, frame wrote:

Of course a double* makes more sense than a void* type for the AA here.

3 days ago

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:

double[string] diagonalLengths;

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

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:

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.