List with no duplicates

G

Guest

Hello, Newsgroupians:

Just a quick question really quick. Does C# have a generic class that will
allow me to add only one instance of an object to the "collection" without
having me do a .Contains() or something similar?

In my case, I have a set of controls a user selects. If the user selects
the same control twice, I don't want it added again to my collection, and I
don't want to handle the exception, and I think .Contains() is too expensive.
Does anyone have any recommendations? I've tried a Dictionary with the key
being the control as well as the value being the control, but again doing
this led to an exception. Is there any other way or generic class that I
should look at?

Thank you.


Trecius
 
N

Nicholas Paldino [.NET/C# MVP]

Trecius,

No, in .NET 3.0 and before, you have to do this yourself with a check to
Contains.

In .NET 3.5, you would use the new HashSet class.

Before that, you can use a Dictionary<TKey, TValue> class. The type
parameter TValue doesn't really matter here. It's TKey that you are
concerned about. The TKey type parameter should be set to the type of the
instances you don't want to duplicate. You can use bool for the TValue, if
you wish.

Then, before you add to the Dictionary, call Contains. If Contains
returns true, then the item exists.
 
T

Tom Porterfield

Nicholas said:
Trecius,

No, in .NET 3.0 and before, you have to do this yourself with a check to
Contains.

In .NET 3.5, you would use the new HashSet class.

Before that, you can use a Dictionary<TKey, TValue> class. The type
parameter TValue doesn't really matter here. It's TKey that you are
concerned about. The TKey type parameter should be set to the type of the
instances you don't want to duplicate. You can use bool for the TValue, if
you wish.

Then, before you add to the Dictionary, call Contains. If Contains
returns true, then the item exists.

It should also be noted that with dictionaries, Contains is really not
an expensive call. It could be if the number of items was really large,
but sounds like the OP is talking about user controls that a user would
select, something that isn't likely to come anywhere near having enough
to cause any performance issues with a call to Contains.
 
P

Peter Duniho

[...]
Then, before you add to the Dictionary, call Contains. If
Contains returns true, then >the item exists.

It should also be noted that with dictionaries, Contains is really not
an expensive call. It could be if the number of items was really
large, but sounds like the OP is talking about user controls that a
user would select, something that isn't likely to come anywhere near
having enough to cause any performance issues with a call to Contains.

I would reverse that. Using a Dictionary<>, the call should not be
expensive regardless, even if the number of elements is large.
Assuming this is a case of dealing with user controls, a plain old tree
traversal is likely to be plenty fast as long as it's not the primary
thing that the program is doing (and it's hard to imagine why it would
be).

Pete
 
N

Norapinephrine

Trecius,

No, in .NET 3.0 and before, you have to do this yourself with a check to
Contains.

In .NET 3.5, you would use the new HashSet class.

Before that, you can use a Dictionary<TKey, TValue> class. The type
parameter TValue doesn't really matter here. It's TKey that you are
concerned about. The TKey type parameter should be set to the type of the
instances you don't want to duplicate. You can use bool for the TValue, if
you wish.

Then, before you add to the Dictionary, call Contains. If Contains
returns true, then the item exists.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)




Hello, Newsgroupians:
Just a quick question really quick. Does C# have a generic class that
will
allow me to add only one instance of an object to the "collection" without
having me do a .Contains() or something similar?
In my case, I have a set of controls a user selects. If the user selects
the same control twice, I don't want it added again to my collection, and
I
don't want to handle the exception, and I think .Contains() is too
expensive.
Does anyone have any recommendations? I've tried a Dictionary with the
key
being the control as well as the value being the control, but again doing
this led to an exception. Is there any other way or generic class that I
should look at?
Thank you.
Trecius- Hide quoted text -

- Show quoted text -

Do you really have to call Contains before updating a Dictionary ?

I mean, I thought that a Dictionary could not _inherently_ contain
multiple entries, because after all it is just a Key-Value pair, not a
Key-ListOfValues pair ?

EG,
The code below should not except and should not store any duplicates!

Dictionary[ objectA.UniqueID ] = "specialValue";
Dictionary[ objectA.UniqueID ] = "anotherSpecialValue"

Right ?
 
N

Norapinephrine

Hello, Newsgroupians:

Just a quick question really quick. Does C# have a generic class that will
allow me to add only one instance of an object to the "collection" without
having me do a .Contains() or something similar?

In my case, I have a set of controls a user selects. If the user selects
the same control twice, I don't want it added again to my collection, and I
don't want to handle the exception, and I think .Contains() is too expensive.
Does anyone have any recommendations? I've tried a Dictionary with the key
being the control as well as the value being the control, but again doing
this led to an exception. Is there any other way or generic class that I
should look at?

Thank you.

Trecius

My solution is outside of the Key-Value box :)

Since we want the list to contain unique values, only store those
values as the KEYS in the Dictionary. The dictionary , by definition,
does not store more than one value per key. You can then copy the
Dictionary.Keys property into a list and rest assured that there are
no duplicates.
 
N

Norapinephrine

My solution is outside of the Key-Value box :)

Since we want the list to contain unique values, only store those
values as the KEYS in the Dictionary. The dictionary , by definition,
does not store more than one value per key. You can then copy the
Dictionary.Keys property into a list and rest assured that there are
no duplicates.- Hide quoted text -

- Show quoted text -

Let me expand :

object inputValue = GetUserSelectedValueFromGUI();

dictionary[inputValue] = 99; // the only thing important here is that
we stored inputValue as a KEY in the dictionary.

....

List<object> noDuplicatesListOfUserInput = dictionary.Keys;

Hope this helps!
 
P

Peter Duniho

[...]
Do you really have to call Contains before updating a Dictionary ?

No, you're right. You can catch an exception instead when calling
Add(), or you can use the Item property as you've suggested.
I mean, I thought that a Dictionary could not _inherently_ contain
multiple entries, because after all it is just a Key-Value pair, not a
Key-ListOfValues pair ?

The keys must be unique, yes.
EG,
The code below should not except and should not store any duplicates!

Dictionary[ objectA.UniqueID ] = "specialValue";
Dictionary[ objectA.UniqueID ] = "anotherSpecialValue"

Right ?

Yes. If the key doesn't already exist, a set operation on the Item
property will create a new entry in the Dictionary with the specified
value. If the key does already exist, the value associated with the
key will be replaced by the specified value.

Pete
 
H

Hilton

Just have:

Hashtable ht = new Hashtable ();

Then use:
this.ht [key] = null;

Using "= 99" as you did raises boxing issues and could create a huge
performance hit.

Hilton
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top