sort, .array and folding on immutable data (finding most common character in column of matrix)

Nicholas Wilson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Dec 18 16:11:49 PST 2016


On Sunday, 18 December 2016 at 22:26:50 UTC, Ali wrote:
> Hey, so I have this data file that has a list of a string of 
> characters separated by new lines. The task is to find the most 
> common letter in each column. Ie if file is:
>
> abc
> axy
> cxc
>
> Then the letters are a (column 1), x and c.
>
> I've written the code to do this at compile time. But I have a 
> few questions about sorting, immutablity casting and the need 
> to use .array. The code follows:
>
> ==================================
> import std.stdio, std.range, std.algorithm;
>
> // Line 1
> static immutable data = 
> import("data_06.txt").split("\n").transposed.map!"a.array.sort().group.array".array;
>
> // Line 2
> alias T = typeof(data[0][0]);
>
> auto redux(T[] charData) {
>     return charData.fold!((a, b) {
>         return a[1] > b[1] ? a : typeof(a)(b[0], b[1]);
>     })(T.init);
> }
>
> // Line 3
> static immutable word = data.map!redux.array.map!"a[0]".array;
>
> void main() {
>     word.writeln;
> }
> ==================================
>
> Well mostly I'm looking for how to simplify this even further. 
> So any hints there would be awesome.
>
> And, there're a few questions I have about the code (I guess 
> mainly because of my of my lack of understanding of the type 
> system)
>
> 1. The first line with the splitting, I need to use .array 
> three times. The last one I understand is because on "line 2" I 
> alias T as the type of the data, and if I don't call .array 
> then it's a MapResult type which has no opIndex. Yes?
>
> 2. On "line 1" I have to call .array.sort(). Why can't I just 
> call .sort() on the transposed rows?
>

Because sort requires a random access range.

> 3. If I call .sort (without parenthesis) I get a compiler 
> error. What up with that?

Unfortunately arrays have a builtin property sort that for some 
reason takes precedence of std.algorithm.sort when called without 
(). The compiler error is probably because .sort is a mutating 
operation and you're working with immutable data.

>
> 4. On "line 3" I call map with the free function "redux". In 
> this function, if I return just "a", it's all good. If I return 
> "b", then I get "Incompatible function/seed/element: 
> __lambda2/Tuple!(dchar, uint)/immutable(Tuple!(dchar, uint))". 
> So my seed is not immutable, but the elements of "data" are. I 
> can understand that. But how do I work around it without having 
> to do "typeof(a)(b[0], b[1])" ?

Try
      })(ImmutableOf!T.init);
or use the seedless version of fold.
may need to import std.traits(?)
>
> 5. Is there anyway to get rid of the the "alias" I have in the 
> code and just use an inline lambda in my map call on "line 3"?

does `data.map!fold!"a[1] > b[1] ? a : b".map!"a[0]".array;` work?



More information about the Digitalmars-d-learn mailing list