www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can't iterate over range

reply Profile Anaysis <PA gotacha.com> writes:
I am trying to iterate over the combinations of a set using the 
code

https://rosettacode.org/wiki/Power_set#D

I have an array which I call powerSet on and I get a result of 
MapResult. I have tried to foreach or front/popFront and even 
each() on it but I can never get the result as the same array 
type that I started with.

What is MapResult(the algorithm that generates the result 
lazily?) and how do we easily iterate over the results like we 
would with an array?
Feb 04 2017
parent reply ag0aep6g <anonymous example.com> writes:
On 02/04/2017 12:31 PM, Profile Anaysis wrote:
 I am trying to iterate over the combinations of a set using the code

 https://rosettacode.org/wiki/Power_set#D

 I have an array which I call powerSet on and I get a result of
 MapResult. I have tried to foreach or front/popFront and even each() on
 it but I can never get the result as the same array type that I started
 with.
To create an array from a range, you can use std.array.array:
 What is MapResult(the algorithm that generates the result lazily?)
Yes, it's a struct that gives you one element at a time, lazily generated.
 and
 how do we easily iterate over the results like we would with an array?
foreach and empty/front/popFront should both work. If you can't get them to work, show what you tried.
Feb 04 2017
parent reply Profile Anaysis <PA gotacha.com> writes:
On Saturday, 4 February 2017 at 14:35:37 UTC, ag0aep6g wrote:
 On 02/04/2017 12:31 PM, Profile Anaysis wrote:
 I am trying to iterate over the combinations of a set using 
 the code

 https://rosettacode.org/wiki/Power_set#D

 I have an array which I call powerSet on and I get a result of
 MapResult. I have tried to foreach or front/popFront and even 
 each() on
 it but I can never get the result as the same array type that 
 I started
 with.
To create an array from a range, you can use std.array.array:
 What is MapResult(the algorithm that generates the result 
 lazily?)
Yes, it's a struct that gives you one element at a time, lazily generated.
 and
 how do we easily iterate over the results like we would with 
 an array?
foreach and empty/front/popFront should both work. If you can't get them to work, show what you tried.
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. 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(); 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.
Feb 04 2017
parent ag0aep6g <anonymous example.com> writes:
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; ----
Feb 04 2017