Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / September 2007

Tip: Looking for answers? Try searching our database.

SortedList or Dictionary of KEYS ONLY

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
pamela fluente - 28 Sep 2007 11:11 GMT
I noticed that I am using quite often SortedLists where I use KEYS
only.

when I add new elements I use something like :   MyKeyObj  ,
Nothing/Null/false

Is there a collection type which is similar to the SortedList by does
NOT
have the Values ?

And, a similar question, I have for the Dictionary.

-P
Armin Zingler - 28 Sep 2007 12:12 GMT
> I noticed that I am using quite often SortedLists where I use KEYS
> only.
[quoted text clipped - 7 lines]
>
> And, a similar question, I have for the Dictionary.

Did you know that there are .Net Framework groups for language independent
questions? You can find them here: m.p.dotnet.framework[.*]

Armin
pamela fluente - 28 Sep 2007 14:02 GMT
> Did you know that there are .Net Framework groups for language independent
> questions? You can find them here: m.p.dotnet.framework[.*]

you do not want me here !?  :-))

Cheers,

-P

PS
Thanks, actually I did not know that!

> Armin
Armin Zingler - 28 Sep 2007 14:32 GMT
> > Did you know that there are .Net Framework groups for language
> > independent questions? You can find them here:
> > m.p.dotnet.framework[.*]
>
> you do not want me here !?  :-))

I didn't say this. You're always welcome! Just makes sense to use the groups
for which they are made for. :-)

Armin
Samuel R. Neff - 28 Sep 2007 12:53 GMT
We use a custom collection called KeySet<T> for a dictionary of keys
only since this scenario comes up a lot.  It's made programming these
things a lot easier to read and maintain.

Watch the line wrapping...

HTH,

Sam

------------------------------------------------------------
We're hiring!  B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC.  Work with a variety of technologies
in a relaxed team environment.  See ads on Dice.com.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace Common
{
 /// <summary>
 /// Provides a collection of unordered unique keys.
 /// </summary>
 /// <typeparam name="T">The type of keys to collection</typeparam>
 /// <remarks>
 /// KeySet is similar to a Dictionary but does not contain a value
and is useful when one only cares about existence of
 /// keys and not values associated with them.
 /// </remarks>
 [DebuggerStepThrough]
 public class KeySet<T> : IDictionary<T, bool>, ICollection<T>,
IEnumerable<T>, ICollection
 {
   #region Data

   private Dictionary<T, bool> _dictionary;

   #endregion

   #region Constructors

   public KeySet() : this(0)
   {
   }

   public KeySet(IEqualityComparer<T> comparer) : this(0, comparer)
   {      
   }

   public KeySet(int capactity)
     : this(capactity, null)
   {
   }

   public KeySet(int capactity, IEqualityComparer<T> comparer)
   {
     _dictionary = new Dictionary<T, bool>(capactity, comparer);
   }

   public KeySet(ICollection<T> collection) : this(collection, null)
   {
   }

   public KeySet(ICollection<T> collection, IEqualityComparer<T>
comparer)
   {
     if (collection == null)
     {
       throw new ArgumentNullException("collection");
     }
     _dictionary = new Dictionary<T, bool>(collection.Count,
comparer);
     foreach (T key in collection)
     {
       _dictionary[key] = true;
     }
   }

   #endregion

   #region Public Properties

   public int Count
   {
     get
     {
       return _dictionary.Count;
     }
   }

   public ICollection<T> Keys
   {
     get
     {
       return _dictionary.Keys;
     }
   }

   public bool IsReadOnly
   {
     get
     {
       return false;
     }
   }

   /// <summary>
   /// Returns true if the key exists in the collection, false
otherwise.
   /// </summary>
   /// <param name="key">Key to check for.</param>
   /// <returns>True if key exists in collection.</returns>
   /// <remarks>
   /// Setting a value to false will remove the key from the
collection if it exists.
   ///
   /// Unlike IDictionary&lt;&gt> the indexer will not throw an
exception on an non-existent key, it will simply return false.
   /// </remarks>
   public bool this[T key]
   {
     get
     {
       return _dictionary.ContainsKey(key);
     }
     set
     {
       if (value)
       {
         _dictionary[key] = true;
       }
       else
       {
         _dictionary.Remove(key);          
       }
     }
   }

   #endregion

   #region Public Methods

   public void Add(T key)
   {
     _dictionary.Add(key, true);
   }

   public void Add(ICollection<T> collection)
   {
     if (collection == null)
     {
       throw new ArgumentNullException("collection");
     }
     foreach(T key in collection)
     {
       _dictionary.Add(key, true);
     }
   }

   ///<summary>
   ///Removes all items from the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.
   ///</summary>
   ///
   ///<exception cref="T:System.NotSupportedException">The <see
cref="T:System.Collections.Generic.ICollection`1"></see> is read-only.
</exception>
   public void Clear()
   {
     _dictionary.Clear();
   }

   public bool Contains(T key)
   {
     return _dictionary.ContainsKey(key);
   }

   public void CopyTo(T[] array, int arrayIndex)
   {
     _dictionary.Keys.CopyTo(array, arrayIndex);
   }

   public IEnumerator<T> GetEnumerator()
   {
     return _dictionary.Keys.GetEnumerator();
   }

   public bool Remove(T key)
   {
     return _dictionary.Remove(key);
   }

   public bool TryGetValue(T key, out bool value)
   {
     return _dictionary.TryGetValue(key, out value);
   }

   #endregion

   #region IDictionary<T,bool> Members

   ///<summary>
   ///Adds an element with the provided key and value to the <see
cref="T:System.Collections.Generic.IDictionary`2"></see>.
   ///</summary>
   ///
   ///<param name="value">The bool to use as the value of the element
to add.</param>
   ///<param name="key">The bool to use as the key of the element to
add.</param>
   ///<exception cref="T:System.NotSupportedException">The <see
cref="T:System.Collections.Generic.IDictionary`2"></see> is
read-only.</exception>
   ///<exception cref="T:System.ArgumentException">An element with
the same key already exists in the <see
cref="T:System.Collections.Generic.IDictionary`2"></see>.</exception>
   ///<exception cref="T:System.ArgumentNullException">key is
null.</exception>
   void IDictionary<T, bool>.Add(T key, bool value)
   {
     if (!value)
     {
       throw TrueOnlyException;
     }
     _dictionary.Add(key, true);
   }

   ///<summary>
   ///Determines whether the <see
cref="T:System.Collections.Generic.IDictionary`2"></see> contains an
element with the specified key.
   ///</summary>
   ///
   ///<returns>
   ///true if the <see
cref="T:System.Collections.Generic.IDictionary`2"></see> contains an
element with the key; otherwise, false.
   ///</returns>
   ///
   ///<param name="key">The key to locate in the <see
cref="T:System.Collections.Generic.IDictionary`2"></see>.</param>
   ///<exception cref="T:System.ArgumentNullException">key is
null.</exception>
   bool IDictionary<T, bool>.ContainsKey(T key)
   {
     return _dictionary.ContainsKey(key);
   }

   ///<summary>
   ///Gets an <see
cref="T:System.Collections.Generic.ICollection`1"></see> containing
the values in the <see
cref="T:System.Collections.Generic.IDictionary`2"></see>.
   ///</summary>
   ///
   ///<returns>
   ///An <see
cref="T:System.Collections.Generic.ICollection`1"></see> containing
the values in the bool that implements <see
cref="T:System.Collections.Generic.IDictionary`2"></see>.
   ///</returns>
   ///
   ICollection<bool> IDictionary<T, bool>.Values
   {
     get
     {
       return _dictionary.Values;
     }
   }

   #endregion

   #region ICollection<KeyValuePair<T,bool>> Members

   ///<summary>
   ///Removes the first occurrence of a specific bool from the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.
   ///</summary>
   ///
   ///<returns>
   ///true if item was successfully removed from the <see
cref="T:System.Collections.Generic.ICollection`1"></see>; otherwise,
false. This method also returns false if item is not found in the
original <see
cref="T:System.Collections.Generic.ICollection`1"></see>.
   ///</returns>
   ///
   ///<param name="item">The bool to remove from the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
   ///<exception cref="T:System.NotSupportedException">The <see
cref="T:System.Collections.Generic.ICollection`1"></see> is
read-only.</exception>
   bool ICollection<KeyValuePair<T, bool>>.Remove(KeyValuePair<T,
bool> item)
   {
     return _dictionary.Remove(item.Key);
   }

   ///<summary>
   ///Copies the elements of the <see
cref="T:System.Collections.Generic.ICollection`1"></see> to an <see
cref="T:System.Array"></see>, starting at a particular <see
cref="T:System.Array"></see> index.
   ///</summary>
   ///
   ///<param name="array">The one-dimensional <see
cref="T:System.Array"></see> that is the destination of the elements
copied from <see
cref="T:System.Collections.Generic.ICollection`1"></see>. The <see
cref="T:System.Array"></see> must have zero-based indexing.</param>
   ///<param name="arrayIndex">The zero-based index in array at which
copying begins.</param>
   ///<exception
cref="T:System.ArgumentOutOfRangeException">arrayIndex is less than
0.</exception>
   ///<exception cref="T:System.ArgumentNullException">array is
null.</exception>
   ///<exception cref="T:System.ArgumentException">array is
multidimensional.-or-arrayIndex is equal to or greater than the length
of array.-or-The number of elements in the source <see
cref="T:System.Collections.Generic.ICollection`1"></see> is greater
than the available space from arrayIndex to the end of the destination
array.-or-Type T cannot be cast automatically to the type of the
destination array.</exception>
   void ICollection<KeyValuePair<T, bool>>.CopyTo(KeyValuePair<T,
bool>[] array, int arrayIndex)
   {
     ((ICollection<KeyValuePair<T, bool>>) _dictionary).CopyTo(array,
arrayIndex);
   }

   ///<summary>
   ///Determines whether the <see
cref="T:System.Collections.Generic.ICollection`1"></see> contains a
specific value.
   ///</summary>
   ///
   ///<returns>
   ///true if item is found in the <see
cref="T:System.Collections.Generic.ICollection`1"></see>; otherwise,
false.
   ///</returns>
   ///
   ///<param name="item">The bool to locate in the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
   bool ICollection<KeyValuePair<T, bool>>.Contains(KeyValuePair<T,
bool> item)
   {
     return _dictionary.ContainsKey(item.Key);
   }

   ///<summary>
   ///Adds an item to the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.
   ///</summary>
   ///
   ///<param name="item">The bool to add to the <see
cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
   ///<exception cref="T:System.NotSupportedException">The <see
cref="T:System.Collections.Generic.ICollection`1"></see> is
read-only.</exception>
   void ICollection<KeyValuePair<T, bool>>.Add(KeyValuePair<T, bool>
item)
   {
     if (item.Value)
     {
       throw TrueOnlyException;
     }
     _dictionary.Add(item.Key, true);
   }

   #endregion

   #region ICollection Members

   ///<summary>
   ///Copies the elements of the <see
cref="T:System.Collections.ICollection"></see> to an <see
cref="T:System.Array"></see>, starting at a particular <see
cref="T:System.Array"></see> index.
   ///</summary>
   ///
   ///<param name="array">The one-dimensional <see
cref="T:System.Array"></see> that is the destination of the elements
copied from <see cref="T:System.Collections.ICollection"></see>. The
<see cref="T:System.Array"></see> must have zero-based indexing.
</param>
   ///<param name="index">The zero-based index in array at which
copying begins. </param>
   ///<exception cref="T:System.ArgumentNullException">array is null.
</exception>
   ///<exception cref="T:System.ArgumentOutOfRangeException">index is
less than zero. </exception>
   ///<exception cref="T:System.ArgumentException">array is
multidimensional.-or- index is equal to or greater than the length of
array.-or- The number of elements in the source <see
cref="T:System.Collections.ICollection"></see> is greater than the
available space from index to the end of the destination array.
</exception>
   ///<exception cref="T:System.InvalidCastException">The type of the
source <see cref="T:System.Collections.ICollection"></see> cannot be
cast automatically to the type of the destination array.
</exception><filterpriority>2</filterpriority>
   void ICollection.CopyTo(Array array, int index)
   {
     ((IDictionary) _dictionary).Keys.CopyTo(array, index);
   }

   ///<summary>
   ///Gets an object that can be used to synchronize access to the
<see cref="T:System.Collections.ICollection"></see>.
   ///</summary>
   ///
   ///<returns>
   ///An object that can be used to synchronize access to the <see
cref="T:System.Collections.ICollection"></see>.
   ///</returns>
   ///<filterpriority>2</filterpriority>
   object ICollection.SyncRoot
   {
     get
     {
       return ((ICollection) _dictionary).SyncRoot;
     }
   }

   ///<summary>
   ///Gets a value indicating whether access to the <see
cref="T:System.Collections.ICollection"></see> is synchronized (thread
safe).
   ///</summary>
   ///
   ///<returns>
   ///true if access to the <see
cref="T:System.Collections.ICollection"></see> is synchronized (thread
safe); otherwise, false.
   ///</returns>
   ///<filterpriority>2</filterpriority>
   bool ICollection.IsSynchronized
   {
     get
     {
       return ((ICollection)_dictionary).IsSynchronized;
     }
   }

   #endregion

   #region IEnumerable<KeyValuePair<T,bool>> Members

   ///<summary>
   ///Returns an enumerator that iterates through the collection.
   ///</summary>
   ///
   ///<returns>
   ///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see>
that can be used to iterate through the collection.
   ///</returns>
   ///<filterpriority>1</filterpriority>
   IEnumerator<KeyValuePair<T, bool>> IEnumerable<KeyValuePair<T,
bool>>.GetEnumerator()
   {
     return ((IEnumerable<KeyValuePair<T, bool>>)
_dictionary).GetEnumerator();
   }

   #endregion

   #region IEnumerable Members

   ///<summary>
   ///Returns an enumerator that iterates through a collection.
   ///</summary>
   ///
   ///<returns>
   ///An <see cref="T:System.Collections.IEnumerator"></see> bool
that can be used to iterate through the collection.
   ///</returns>
   ///<filterpriority>2</filterpriority>
   IEnumerator IEnumerable.GetEnumerator()
   {
     return _dictionary.Keys.GetEnumerator();
   }

   #endregion

   #region Private Helpers

   private static ArgumentException TrueOnlyException
   {
     get
     {
       return new ArgumentException("KeySet only supports 'true'
values.");
     }
   }

   #endregion

 }
}

>I noticed that I am using quite often SortedLists where I use KEYS
>only.
[quoted text clipped - 9 lines]
>
>-P
pamela fluente - 28 Sep 2007 14:00 GMT
> We use a custom collection called KeySet<T> for a dictionary of keys
> only since this scenario comes up a lot.  It's made programming these
[quoted text clipped - 5 lines]
>
> Sam

Thanks Sam,

 It's very generous of you to provide your code.

  I was also thinking to do the same (actually more simple :-). By
inheriting from
  a SortedList  of Key, Boolean or a Dictionary of Key, Boolean and
"shielding"
  the Values.

 But I guess that would not be much different from using the standard
 classes and adding Null Values.

It's strange Microsoft dose not seem to provide them (does it?).
Since one has custom comparers in .NET
its quite natural that the Key can hold all the necessary
information. No?

-P
Niels Ull - 28 Sep 2007 15:07 GMT
You might want to look into one of the free collection libraries, e.g. "C5"
or "Power Collections" - these have lots of diffrent Set implementations.
pamela fluente - 28 Sep 2007 16:59 GMT
> You might want to look into one of the free collection libraries, e.g. "C5"
> or "Power Collections" - these have lots of diffrent Set implementations.

I have just looked at Power Collections. I did not know they existed.

Thanks,

-P
Cor Ligthert[MVP] - 28 Sep 2007 17:50 GMT
Pamela,

Have a look at Arrays

Cor

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.