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?