Can't iterate over range

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Feb 4 08:58:26 PST 2017


On 02/04/2017 03:53 PM, Profile Anaysis wrote:
> well, I simply took the code from the page I linked and did a front() on
> the MapResult and it say the type was wrong. I thought it would give me
> the type I put in which was an array.

In the code you can see that powerSet does two levels of `map`. I.e., 
the return value of powerSet is a MapResult whose elements are 
`MapResult`s again. You get a range of ranges back, not a range of arrays.

> I guess maybe I needed to convert it to an array though... but I didn't
> try. I moved on it iterating over it manually.
>
> someStruct[] X;
> someStruct[] x = powerSet(X).popFront();

popFront doesn't return anything. It alters the range on which you call 
it. And as with front, powerSet's return type does not involve the array 
type someStruct[].

Here's how you iterate over the range with empty, front, popFront:

----
SomeStruct[] a;
auto r = powerSet(a);
while (!r.empty)
{
     auto subset = r.front;

     /* subset is another range, not a SomeStruct[].
     To iterate over it, you can use the range primitives again: */

     while (!subset.empty)
     {
         SomeStruct element = subset.front; /* Finally, a simple type. */
         /* ... do something with element ... */
         subset.popFront();
     }

     r.popFront();
}
----

Note the `auto` types for r and subset. You usually don't type out the 
types of such ranges, because they're too complicated.

Or using foreach:

----
foreach (subset; r)
{
     foreach (element; subset)
     {
         /* ... do something with element which is a SomeStruct ... */
     }
}
----

> gave me an error. Was saying I was getting another MapResult, which I
> thought it shouldn't but maybe I just needed to convert it to an array.

To convert each of the ranges you get from powerSet to SomeStruct[], 
call std.array.array on it:

----
foreach (subset; r)
{
     import std.array: array;
     SomeStruct[] subsetArr = subset.array;
     /* ... do something with subsetArr ... */
}
----

To convert the whole result to SomeStruct[][], you can either just 
append those `subsetArr`s manually to an array:

----
SomeStruct[][] a2;
foreach (subset; r)
{
     import std.array: array;
     SomeStruct[] subsetArr = subset.array;
     a2 ~= subsetArr;
}
----

Or combine std.array.array with std.algorithm.map:

----
import std.array: array;
SomeStruct[][] a2 = r.map!array.array;
----


More information about the Digitalmars-d-learn mailing list