Better idea for double list comprehension?

Stanislav Blinov stanislav.blinov at gmail.com
Sat Jan 18 19:39:22 PST 2014


On Sunday, 19 January 2014 at 02:10:01 UTC, CJS wrote:

> That's more concise but I also think it's more confusing. I 
> assume that to!string is doing the exact same thing, but I was 
> hoping for something to do the appropriate implicit 
> conversations. Especially to a range of length 1, though I can 
> understand that kind of auto-magical conversion would be 
> annoying in a number of important instances.

Does not compute. You mean implicit conversion of single 
character to a range?

> I changed the code to this:
>
> import std.stdio : writeln;
> import std.range : chunks, chain;
> import std.algorithm;
> import std.array;
> import std.conv;
>
> auto cross(R1, R2)(R1 A, R2 B) {
>     return cartesianProduct(A, B).map!(ab => ab[].text).array;
> }
>
>
> void main(){
>     const string letters = "ABCDEFGHI";
>     const string digits = "123456789";
>
>     auto cols = digits;
>     auto rows = letters;
>
>     auto squares = cross(rows, cols);
>     string[][] unitlist;

You may want to use an appender here. It's more efficient than ~= 
, and lets you transform those foreach loops into one-liners :)

       auto app = appender(&unitlist);

       /+
       foreach(c; cols){
           unitlist ~= cross(rows, to!string(c));
       }
       foreach(r; rows){
           unitlist ~= cross(to!string(r), cols);
       }
       foreach(r; chunks(rows, 3)){
           foreach(c; chunks(cols, 3)){
               unitlist ~= cross(to!string(r),to!string(c));
           }
       }
       +/
       app.put(cols.map!(x => cross(rows, x.text)));
       app.put(rows.map!(x => cross(x.text, cols)));
       app.put(chunks(rows,3).map!(r => chunks(cols,3).map!(c => 
cross(r.text, c.text))));

>     string[][][string] units;
>     string[][string] peers;
>
>     foreach(s; squares){
>         units[s] = unitlist.filter!(x => any!(y => s==y)); 
> \\line 37
>     }

This one seems like it should be unitlist.filter!(x => x.any!(y 
=> s==y)).array();

>     foreach(s; squares){
>         peers[s] = remove(chain(units[s]), s); \\line 41
>     }

This one I don't understand. chain(units[s]) ? That's the same as 
units[s]. remove() returns a range, in this case string[][].


More information about the Digitalmars-d-learn mailing list