Filtering a tuple of containers with indices

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Nov 17 12:37:16 PST 2015


On 17.11.2015 20:46, maik klein wrote:
> .selectFromTuple!(0, 1).expand
>
> Does this result in a copy? I avoided doing it like this because I was
> worried that I would copy every array. But I also don't fully understand
> when D will copy.

Yes and no. It copies the Array structs, but it does not copy the 
elements of the arrays. If I remember correctly, std.container.Array 
uses reference counting, and copying them should be cheap.

By the way, do you have a good reason to go with Array!int rather than 
int[]? They're similar, but the builtin int[] may be easier to handle.

> Also doing
>
>    foreach(e;range){
>      e[0] = 10;
>      e[1] = 10.0f;
>      writeln("element: ",e);
>    }
>    foreach(e;range){
>      writeln("element: ",e);
>    }
>
> doesn't mutate the range at all.

You need to mark the `e` as `ref`: `foreach(ref e; range)`. Otherwise, 
it's a copy of the element, and any changes to it are forgotten at the 
end of the iteration.

But even with `ref` it doesn't work. Seems to be a bug in or a 
limitation of `zip`. Works with `lockstep`:
----
   auto ranges = integrals
     .selectFromTuple!(0, 1).expand
     .mapTuple!(a => a[]).expand;
   auto range = ranges.zip;

   import std.range: lockstep;
   foreach(ref e0, ref e1; lockstep(ranges)){
     e0 = 10;
     e1 = 10.0f;
   }
   foreach(e;range){
     writeln("element: ",e);
   }
----


More information about the Digitalmars-d-learn mailing list