www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using sets in associative arrays

reply Ralph <ralph mail.com> writes:
Hi there,

I know it is possible to declare an associative array which takes 
arrays as values, i.e.
**int[][int] arr;**
A sample of this could be
**arr[2] = [2, 3, 2, 4, 5];**

I was wondering if there was a way to have this with sets instead 
of arrays. In D, sets are equivalent to red-black trees, afaik. 
Almost as expected, the declaration
**redBlackTree[int] arr;**
such that (according to the initial example) **arr[2]** would be 
[2, 3, 4, 5]
does not work.

Would anybody know of a workaround?
Nov 11
next sibling parent Olivier Pisano <olivier.pisano laposte.net> writes:
Hello,

In your case, the type "set of integers" would be written as 
`RedBlackTree!int` in D. Note that it starts with an uppercase R, 
and takes the type of values to contain as template argument (the 
int after the exclamation mark).

Btw, in the standard library, types always start with an 
uppercase character, it is a convention that will help you later.

I can then use this type to declare an associated array of sets 
of integers such as


     void main()
     {
         RedBlackTree!int[int] assoset;
         assoset[2] = redBlackTree(2, 3, 4, 5);
     }


In my example the first line declares an empty associative array 
that maps sets of integers to integers. I believe this is what 
you wanted.

The second line may look a bit confusing : `redBlackTree` starts 
with a lowercase character and does not contain template type 
argument. It is a function, not a type. This function takes 
variadic arguments and creates a `RedBlackTree` of the type of 
its arguments. Here, `2, 3, 4, 5` are ints, so it returns a 
`RedBlackTree!int`. You may think of it like a constructor or a 
factory function.

The standard library is full of these convenience functions, 
because function templates, contrary to struct/class templates, 
can deduce their template arguments, and avoid the need of 
precising every detail when it is obsvious.

I hope it helps.
Nov 11
prev sibling parent reply Sergey <kornburn yandex.ru> writes:
On Tuesday, 12 November 2024 at 00:42:41 UTC, Ralph wrote:
 Hi there,

 I know it is possible to declare an associative array which 
 takes arrays as values, i.e.
 **int[][int] arr;**
 A sample of this could be
 **arr[2] = [2, 3, 2, 4, 5];**

 I was wondering if there was a way to have this with sets 
 instead of arrays. In D, sets are equivalent to red-black 
 trees, afaik. Almost as expected, the declaration
 **redBlackTree[int] arr;**
 such that (according to the initial example) **arr[2]** would 
 be [2, 3, 4, 5]
 does not work.

 Would anybody know of a workaround?
D's std container situation is quite bad. redBlackTree is one workaround about sets for sure. Another way to simulate it - is using another AA with bool/void parameters. ```d bool[int][int] dict_of_sets; dict_of_sets[1] = [1:true, 2:true, 3:true]; dict_of_sets[1][4] = true; writeln(dict_of_sets); // [1:[4:true, 3:true, 2:true, 1:true]] ```
Nov 11
parent Ralph <ralph mail.com> writes:
On Tuesday, 12 November 2024 at 07:47:58 UTC, Sergey wrote:
 On Tuesday, 12 November 2024 at 00:42:41 UTC, Ralph wrote:
 Hi there,

 I know it is possible to declare an associative array which 
 takes arrays as values, i.e.
 **int[][int] arr;**
 A sample of this could be
 **arr[2] = [2, 3, 2, 4, 5];**

 I was wondering if there was a way to have this with sets 
 instead of arrays. In D, sets are equivalent to red-black 
 trees, afaik. Almost as expected, the declaration
 **redBlackTree[int] arr;**
 such that (according to the initial example) **arr[2]** would 
 be [2, 3, 4, 5]
 does not work.

 Would anybody know of a workaround?
Thank you both for your help!
Nov 12