I want to keep an ordered set of records and the standard provides me with RedBlackTree. The record is of type Tuple!(string, uint). Here's what it looks like:
import std.json : parseJSON;
uint[string] wordTable;
import std.datetime.stopwatch : StopWatch, AutoStart;
auto sw = StopWatch(AutoStart.yes);
const auto j = parseJSON(get(link));
const long downloadTime = sw.peek.total!"msecs";
import std.typecons : Tuple, tuple;
import std.container.rbtree : RedBlackTree;
import std.functional : binaryFun;
RedBlackTree!(Tuple!(string, uint), binaryFun!("a[1] > b[1]")) records;
foreach (node; j["posts"].array()) {
import std.stdio : writeln;
import std.utf : decode;
if ("com" in node) {
import std.algorithm : splitter;
foreach (word; getStr(node["com"].str()).splitter(' ')) {
import std.string : strip;
if (word.strip().length > 0)
wordTable.require(word, 0)++;
records ~= (tuple(word, wordTable[word])); // error
}
}
}
Now primarily I had used insert()
method to add a record to the records but it causes segfault in runtime. So I decided to use ~= in hopes for better error messages. And here's what the compiler says:
Error: cannot append type Tuple!(string, uint) to type std.container.rbtree.RedBlackTree!(Tuple!(string, uint), binaryFun, false)
According to https://dlang.org/phobos/std_container_rbtree.html#.RedBlackTree I have to provide a type such that calling less(a, b)
on it returns a boolean. So I went ahead and created a type for it:
struct Record {
string key;
uint value;
int opCmp(ref const Record other) const {
return value - other.value;
}
}
// bool less(Record a, Record b) {
// return a < b;
// }
void main(string[] args) {
import std.stdio : writeln, writefln;
if (args.length < 3) {
writeln("Must have 2 arguments " ~ "first argument is the link, "
~ "the second one is for minimum repeatation threshold. Exiting.");
import core.stdc.stdlib : exit;
exit(-1);
}
const auto link = parseLink(args[1]);
const auto threshold = atoui(args[2]);
import std.json : parseJSON;
uint[string] wordTable;
import std.datetime.stopwatch : StopWatch, AutoStart;
auto sw = StopWatch(AutoStart.yes);
const auto j = parseJSON(get(link));
const long downloadTime = sw.peek.total!"msecs";
import std.container.rbtree : RedBlackTree;
import std.functional : binaryFun;
RedBlackTree!Record records;
foreach (node; j["posts"].array()) {
import std.utf : decode;
if ("com" in node) {
import std.algorithm : splitter;
foreach (word; getStr(node["com"].str()).splitter(' ')) {
import std.string : strip;
if (word.strip().length > 0)
wordTable.require(word, 0)++;
records ~= (Record(word, wordTable[word]));
}
}
}
This time the compiler complains:
Error: cannot append type Record to type std.container.rbtree.RedBlackTree!(Record, "a < b", false)
So the gist of the question is, if I have an RedBlackTree with a custom binaryFun
, how can I add an instance of a tuple or a custom type to it?