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?

Reply via email to