I was fishing around in D’s standard library looking for a Set implementation, and I only found these:
- BinaryHeap
- RedBlackTree
These both would work fine, if I could only figure out how to use them. I started with the RedBlackTree (because I’m already familiar with how they work), and this is what I came up with:
auto rbt = redBlackTree!string();
foreach(s; setOfStrings) {
rbt.insert(s);
}
foreach(s; rbt) {
if (s[0 .. 3] == "sth") {
rbt.removeKey(s);
}
}
I know I could have done the condition in the first foreach, but it’s just an example showing that I need to add and remove elements from the Set. This would work, but I get compile errors:
Error: template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) does not match any function template declaration
Error: template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) cannot deduce template function from argument types !()(string
I don’t need a red-black tree (anything without duplicates), and speed isn’t too important. I could do something like this:
string[] arr;
foreach(s; setOfStrings) {
// check for duplicate code here...
arr ~= s;
}
for(int i = 0; i < arr.length; i++) {
if (s[0 .. 3] == "sth") {
arr = arr[0 .. i] ~ arr[i + 1 .. $];
i++;
}
}
Is there anything in the standard library for a simple Set?
RedBlackTreeis Phobos’ set implementation. The problem that you’re running into withremoveKeyis the fact that it’s variadic. It will take either an array of keys to remove or multiple keys (e.g.removeKey(arr)orremoveKey(key1, key2, key3)).stringis an array of immmutable chars, so it tries to instantiateremoveKeywithcharinstead ofstring, which doesn’t work, because your tree holds strings, not chars. You wouldn’t have this sort of problem if you were dealing with aRedBlackTreeof ints or any other non-array type.What you need to do is either give it an array of strings or to instantiate it directly i.e.
removeKey([s])orremoveKey!string(s).By the way, std.container has gone the route of naming its container types based on their data structure rather than what they’re used for. So, when you say that you don’t need a red-black tree, that’s not quite right. You want a set. You just don’t care how it’s implemented. The two typical ways to implement sets involve using either a red-black tree or a hash table. So,
RedBlackTreegives you one way to have a set. It’s just that its named after its data structure, not how you might use it, so if you’re looking for a container nameSetin std.container, you’re not going to find it.EDIT: A bug report exists for this, and a fix has been submitted. So, in a future release of dmd, it should be possible to pass a
stringtoremoveKeywithout having to directly instantiate it or pass thestringin inside an array.