Thread overview
Comparison of two 'dynamic arrays'.
Nov 13, 2022
DLearner
Nov 13, 2022
Siarhei Siamashka
Nov 13, 2022
DLearner
Nov 13, 2022
matheus.
Nov 13, 2022
DLearner
Nov 13, 2022
matheus.
Nov 13, 2022
Siarhei Siamashka
November 13, 2022

Hi

Program has two steps:

  1. Creates an array (int[] A), whose size and element values are only known at run-time.

Then:
2. The elements (but not the array size) are further processed in a way that may or may not alter their value.

Requirement: to identify the indices (if any) of the elements whose value changed in step 2.

What is the recommended way to do this?

Creating a step 1.5:

int[] B = A;

And then step 2.5:

for (int j=0, j < A.length, j = j+1) {

   if (B[j] != A[J]) {
      < write the j value away somewhere>
   } else {
   }
}

Won't work, as any step 2 changes to A will be reflected in B.

In passing,is 'dynamic array' a good title for a structure/concept that seems more of a 'view'?
Surely 'dynamic array' is best used for something that is (no more than) a static array whose dimensions can vary at run time?

Best regards

November 13, 2022

On Sunday, 13 November 2022 at 14:28:45 UTC, DLearner wrote:

>

Creating a step 1.5:

int[] B = A;
auto B = A.dup;

This will create a copy of A rather than referencing to the same buffer in memory.

November 13, 2022

On Sunday, 13 November 2022 at 14:39:26 UTC, Siarhei Siamashka wrote:

>

On Sunday, 13 November 2022 at 14:28:45 UTC, DLearner wrote:

>

Creating a step 1.5:

int[] B = A;
auto B = A.dup;

This will create a copy of A rather than referencing to the same buffer in memory.

Tested:

void main() {

   import std.stdio;


   struct test_struct {
      char[] Txt;
   }

   test_struct[] A;


   A.length = 1;
   A[0].Txt.length = 1;
   A[0].Txt[0] = 'X';

   writeln(A);


   auto B = A.dup;

   writeln(A, B);

   A[0].Txt[0] = 'Y';

   writeln(A, B);
}

Got:

[test_struct("X")]
[test_struct("X")][test_struct("X")]
[test_struct("Y")][test_struct("Y")]

Expected last line to be Y,X not Y,Y.

November 13, 2022
On Sunday, 13 November 2022 at 15:45:40 UTC, DLearner wrote:
> On Sunday, 13 November 2022 at 14:39:26 UTC, Siarhei Siamashka wrote:
>> On Sunday, 13 November 2022 at 14:28:45 UTC, DLearner wrote:
>>> Creating a step 1.5:
>>> ```
>>> int[] B = A;
>>> ```
>>
>> ```D
>> auto B = A.dup;
>> ```
>>
>> This will create a copy of A rather than referencing to the same buffer in memory.
>
> Tested:
>
> ```
> void main() {
>
>    import std.stdio;
>
>
>    struct test_struct {
>       char[] Txt;
>    }
>
>    test_struct[] A;
>
>
>    A.length = 1;
>    A[0].Txt.length = 1;
>    A[0].Txt[0] = 'X';
>
>    writeln(A);
>
>
>    auto B = A.dup;
>
>    writeln(A, B);
>
>    A[0].Txt[0] = 'Y';
>
>    writeln(A, B);
> }
>
> ```
>
> Got:
> ```
> [test_struct("X")]
> [test_struct("X")][test_struct("X")]
> [test_struct("Y")][test_struct("Y")]
> ```
>
> Expected last line to be Y,X not Y,Y.

You should add the code below after "auto B = A.dup;":

   B[0].Txt = A[0].Txt.dup;

The "Txt" property inside B is still referencing A without the above.

Matheus.
November 13, 2022

On Sunday, 13 November 2022 at 15:45:40 UTC, DLearner wrote:

>
   struct test_struct {
      char[] Txt;
   }
   test_struct[] A;
   auto B = A.dup;

But A is not an int[] in your new example. You need a "deep copy" and I can see that similar questions had been asked in this forum before: https://forum.dlang.org/thread/yzvcyyqadpttqvtiefhn@forum.dlang.org

Maybe you can add a copy constructor to your struct, which would dup Txt?

November 13, 2022

On Sunday, 13 November 2022 at 16:11:17 UTC, matheus. wrote:
[...]

>

You should add the code below after "auto B = A.dup;":

B[0].Txt = A[0].Txt.dup;

The "Txt" property inside B is still referencing A without the above.

Matheus.

Thank you - your suggestion worked.

The slight generalisation shown at bottom also worked.

However, is there a way of avoiding the for-loop?
Things like

B[].Txt = A[].Txt.dup;

did not work for me.

void main() {

   import std.stdio;

   int index;
   struct test_struct {
      char[] Txt;
   }

   test_struct[] A;

   A.length = 2;
   A[0].Txt.length = 1;
   A[1].Txt.length = 1;

   A[0].Txt[0] = 'W';
   A[1].Txt[0] = 'X';

   writeln(A);

   auto B = A.dup;
   for (index = 0; index < A.length; index = index + 1) {
      B[index].Txt = A[index].Txt.dup;
   }

   writeln(A, B);

   A[0].Txt[0] = 'Y';
   A[1].Txt[0] = 'Z';

   writeln(A, B);
}
November 13, 2022
On Sunday, 13 November 2022 at 17:10:23 UTC, DLearner wrote:
> ...
> The slight generalisation shown at bottom also worked.
>
> However, is there a way of avoiding the for-loop?
> ...

I don't have too much knowledge in D, but I think so. (My main language is C).

Well, one way to make things "better" would be creating a constructor inside that struct with opCall, something like this:

import std.stdio;

void main() {
   struct test_struct {
      char[] Txt;
      static test_struct[] opCall(test_struct[] e){
        auto _ = e.dup;
        foreach(i,v; e[0].Txt){
            _[0].Txt = e[0].Txt.dup;
        }
        return _;
    }
   }
   test_struct[] A;
   A.length = 1;
   A[0].Txt.length = 1;
   A[0].Txt[0] = 'X';
   writeln(A);
   auto B = test_struct(A);
   writeln(A, B);
   A[0].Txt[0] = 'Y';
   writeln(A, B);
}

There still a loop over there, so let's wait for some advanced users to destroy this. :)

Matheus.