Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve actual item from HashSet<T>?

Tags:

c#

.net

hashset

I've read this question about why it is not possible, but haven't found a solution to the problem.

I would like to retrieve an item from a .NET HashSet<T>. I'm looking for a method that would have this signature:

/// <summary> /// Determines if this set contains an item equal to <paramref name="item"/>,  /// according to the comparison mechanism that was used when the set was created.  /// The set is not changed. If the set does contain an item equal to  /// <paramref name="item"/>, then the item from the set is returned. /// </summary> bool TryGetItem<T>(T item, out T foundItem); 

Searching the set for an item with such a method would be O(1). The only way to retrieve an item from a HashSet<T> is to enumerate all items which is O(n).

I haven't find any workaround to this problem other then making my own HashSet<T> or use a Dictionary<K, V>. Any other idea?

Note:
I don't want to check if the HashSet<T> contains the item. I want to get the reference to the item that is stored in the HashSet<T> because I need to update it (without replacing it by another instance). The item I would pass to the TryGetItem would be equal (according to the comparison mechanism that I've passed to the constructor) but it would not be the same reference.

like image 204
Francois C Avatar asked Oct 13 '11 21:10

Francois C


People also ask

Can you get from a HashSet?

HashSet does not have a get method to retrieve elements. HashSet implements the Set interface. The Set is a collection with no duplicates. This interface models the mathematical set abstraction.

What is the difference between HashSet T and List T >?

A HashSet<T> is a class designed to give you O(1) lookup for containment (i.e., does this collection contain a particular object, and tell me the answer fast). A List<T> is a class designed to give you a collection with O(1) random access than can grow dynamically (think dynamic array).

What is the return type of HashSet in Java?

Method SummaryReturns a shallow copy of this HashSet instance: the elements themselves are not cloned. Returns true if this set contains the specified element. Returns true if this set contains no elements. Returns an iterator over the elements in this set.


2 Answers

This is actually a huge omission in the set of collections. You would need either a Dictionary of keys only or a HashSet that allows for the retrieval of object references. So many people have asked for it, why it doesn't get fixed is beyond me.

Without third-party libraries the best workaround is to use Dictionary<T, T> with keys identical to values, since Dictionary stores its entries as a hash table. Performance-wise it is the same as the HashSet, but it wastes memory of course (size of a pointer per entry).

Dictionary<T, T> myHashedCollection; ... if(myHashedCollection.ContainsKey[item])     item = myHashedCollection[item]; //replace duplicate else     myHashedCollection.Add(item, item); //add previously unknown item ... //work with unique item 
like image 53
JPE Avatar answered Sep 28 '22 10:09

JPE


What you're asking for was added to .NET Core a year ago, and was recently added to .NET 4.7.2:

In .NET Framework 4.7.2 we have added a few APIs to the standard Collection types that will enable new functionality as follows.
- ‘TryGetValue‘ is added to SortedSet and HashSet to match the Try pattern used in other collection types.

The signature is as follows (found in .NET 4.7.2 and above):

    //     // Summary:     //     Searches the set for a given value and returns the equal value it finds, if any.     //     // Parameters:     //   equalValue:     //     The value to search for.     //     //   actualValue:     //     The value from the set that the search found, or the default value of T when     //     the search yielded no match.     //     // Returns:     //     A value indicating whether the search was successful.     public bool TryGetValue(T equalValue, out T actualValue); 

P.S.: In case you're interested, there is related function they're adding in the future - HashSet.GetOrAdd(T).

like image 34
Evdzhan Mustafa Avatar answered Sep 28 '22 08:09

Evdzhan Mustafa