digitalmars.D.learn - Adding item to a rbtree with a custom binaryFun
- Adnan (35/35) Apr 13 2020 I want to keep an ordered set of records and the standard
- Adnan (36/71) Apr 13 2020 I also tried creating a new type:
- Steven Schveighoffer (9/53) Apr 13 2020 // do this: (note you don't need binaryFun)
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 used `insert()` method to add a record to the records but it causes segfault in runtime. So I decided to use ~= to see what's going on. Here's what the compiler says: Error: cannot append type Tuple!(string, uint) to type std.container.rbtree.RedBlackTree!(Tuple!(string, uint), binaryFun, false) So the gist of the question is, if I have an RedBlackTree with a custom binaryFun, how can I add tuples to it?
Apr 13 2020
On Monday, 13 April 2020 at 23:59:20 UTC, Adnan wrote: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 used `insert()` method to add a record to the records but it causes segfault in runtime. So I decided to use ~= to see what's going on. Here's what the compiler says: Error: cannot append type Tuple!(string, uint) to type std.container.rbtree.RedBlackTree!(Tuple!(string, uint), binaryFun, false) So the gist of the question is, if I have an RedBlackTree with a custom binaryFun, how can I add tuples to it?I also tried creating a new type: struct Record { string k; uint v; int opCmp(ref const Record other) const { return v - other.v; } } bool less(Record a, Record b) { return a < b; } 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]); } } } Compiler says: Error: cannot append type Record to type std.container.rbtree.RedBlackTree!(Recor d, "a < b", false) source/app.d(153,18): Error: no [] operator overload for type Record source/app.d(157,58): Error: no [] operator overload for type Record source/app.d(158,40): Error: no [] operator overload for type Record
Apr 13 2020
On 4/13/20 7:59 PM, Adnan wrote: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;// instead of this:RedBlackTree!(Tuple!(string, uint), binaryFun!("a[1] > b[1]")) records;// do this: (note you don't need binaryFun) auto records = new RedBlackTree!(Tuple!(String, uint), "a[1] > b[1]");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 used `insert()` method to add a record to the records but it causes segfault in runtime.Because RedBlackTree is a class, so you need to initialize it with a call to new.So I decided to use ~= to see what's going on. Here's what the compiler says: Error: cannot append type Tuple!(string, uint) to type std.container.rbtree.RedBlackTree!(Tuple!(string, uint), binaryFun, false)Because RedBlackTree doesn't overload appending. -Steve
Apr 13 2020