Solved

Help!! Sort Hashtable value

Posted on 2004-10-12
11
3,569 Views
Last Modified: 2012-06-27
I need to sort my hashtable by locationName.  I'm using both values cityCode and locationName in my code.  And locationName can be duplicated.

Hashtable cities=new Hashtable();
//SortedList slist = new SortedList();

for(int i=0, j=1;i<total;i++,j++)
{
      string cityCode=list.GetLocation(i).Code;
      string locationName=list.GetLocation(i).Location;
      
      if(!cities.ContainsKey(cityCode))
      {
            //slist.Add(locationName, cityCode);
            cities.Add(cityCode, locationName);
      }
}

ANY HELP APPRECIATED!!! THANKS!!!
0
Comment
Question by:sticar
  • 4
  • 4
  • 3
11 Comments
 
LVL 7

Expert Comment

by:NipNFriar_Tuck
ID: 12291308
Alright create a comparer class like

    class HTComparer : IComparer {
        #region IComparer Members

        public int Compare(object x, object y) {
            // TODO:  Add HTComparer.Compare implementation
            return 0;
        }

        #endregion

    }

Then set the comparer to the hashtable comparer

Hashtable ht = new Hashtable();
ht.comparer = new HTComparer();

If you need help implementing the compare function let me know...
0
 

Author Comment

by:sticar
ID: 12291350
Yes I definitely need help... :)
0
 
LVL 7

Expert Comment

by:NipNFriar_Tuck
ID: 12291405
Realize that object x and object y are just the key values(strings) being passed in and since you are passing in a string you could write something like:

        public int Compare(object x, object y) {
            // TODO:  Add HTComparer.Compare implementation
            return String.Compare( x.ToString(), y.ToString() );
        }
0
 
LVL 14

Expert Comment

by:AvonWyss
ID: 12291462
Er. Why aren't you using a SortedList instead of a Hashtable? This might be what you need, it also offers dictionary fonctionality but it's always sorted. Performance is also quite good (not as fast as a Hashtable, but faster than needing to sort the hashtable contents afterwards).
0
 

Author Comment

by:sticar
ID: 12291613
AvonWyss: I would still have the issue with sorting the "values" instead of the keys right?  And I can't add the Value as the Key because they can be duplicated.  

NipNFriar_Tuck:
I created a class above named HTComparer.cs

Then in another .ascx.cs file I try to call it:
Hashtable cities= new Hashtable();
cities.comparer   //There isn't a "comparer" as an option.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 14

Accepted Solution

by:
AvonWyss earned 500 total points
ID: 12291700
Well, you could work with a SortedList which does not contain strings but lists. This wouls allow you to use Value as key and have multiple associated values.

But there might be another, simpler solution. Try this:

string[] cities=new string[total];
string[] locations=new string[total];
for(int i=0; i<total; i++) {
     cities[i]=list.GetLocation(i).Code;
     location[i]=list.GetLocation(i).Location;
}
Array.Sort(locations, cities);

This sort by location and also does the same array operations on cities, so that the pairs still match.

Another solution could be to implement your own comparer for the objects or structs returned by GetLocation(), then you could have them in a normal array or an ArrayList. Many possibilities here...
0
 
LVL 7

Expert Comment

by:NipNFriar_Tuck
ID: 12292065
Sorry, I was a little off on the implementation...

do

Hashtable ht = new Hashtable( null, new HTComparer() );

during the constructor...
0
 

Author Comment

by:sticar
ID: 12292360
Does this look close to right? I'm not sure on the sort area, it's only comparing the two values passed in, not all the values in locationName.
--------------------------------------------------------------------
                        HTComparer cities = new HTComparer();
                        HTComparer sort = new HTComparer();

                        for(int i=0;i<total;i++)
                        {
                              string cityCode=list.GetLocation(i).Code;
                              string locationName=list.GetLocation(i).Location;

                              if(!cities.ContainsKey(locationName))
                              {
                                    sort.Compare(cityCode, locationName);
                                            cities.Add(cityCode, locationName);
                              }
                        }
                        

my class
--------------------------------------------------------------------
      public class HTComparer :IComparer
      {
            public HTComparer()
            {
                  Hashtable ht = new Hashtable( null, new HTComparer());
            }

            public int Compare(object x, object y)
            {
                  return String.Compare( x.ToString(), y.ToString() );
            }
      }
0
 

Author Comment

by:sticar
ID: 12297937
AvonWyss, I ended up using yours.  It works great!  Thanks!
0
 
LVL 7

Expert Comment

by:NipNFriar_Tuck
ID: 12298333
sticar, your last post was close... here is what it should have looked like...
--------------------------------------------------------------------
                    Hashtable cities = new Hashtable( null, new HTComparer() );
 
                    for(int i=0;i<total;i++)
                    {
                         string cityCode=list.GetLocation(i).Code;
                         string locationName=list.GetLocation(i).Location;

                         if(!cities.ContainsKey(locationName))
                         {
                             cities.Add(cityCode, locationName);
                         }
                    }
                   

my class
--------------------------------------------------------------------
     public class HTComparer :IComparer
     {
          public int Compare(object x, object y)
          {
               return String.Compare( x.ToString(), y.ToString() );
          }
     }

Since a Hashtable sorts keys automagically you do not need to explicitly sort the Hashtable!  The keys are sorted via the comparer that you gave during instantiaion.  By the by this is the alternate solution that AvonWyss gave...  Cheers.
0
 
LVL 14

Expert Comment

by:AvonWyss
ID: 12298405
NipNFriar_Tuck, since the values must be sorted, not the keys, you suggestion does not solve this problem. Also, note that the hashtable is not sorted by the comparer you gave. It's primary sorting key is the hash code, and for two items which land in the same bucket (that is, where the hashcode modulus the number of buckets is equal), they are sorted with the comparer so that the bucket can be searched with a binary search. But your suggestion with the comparer would work fine for a SortedList, if there wasn't that issue with the multiple values with the same value.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now