www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Adding item to a rbtree with a custom binaryFun

reply Adnan <relay.public.adnan outlook.com> writes:
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
next sibling parent Adnan <relay.public.adnan outlook.com> writes:
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
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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