471,052 Members | 1,267 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,052 software developers and data experts.

SortedList - Sort by VALUE (not KEY)

Hi -

Does anyone know a way to created a SortedList (in the
System.Collections namespace) that will sort on VALUES instead of
KEYS... ?

The scenario is this - I have a SortedList containing key-value pairs
of UserID - DisplayName for a whole bunch of user objects. The UserID
is simply a long, the DisplayName is something like, "Jones, Bill". I
want the SortedList to sort the names alphabetically, rather than by
increasing order of UserIDs.

The simple answer is to use the DisplayName as a key, and UserID as a
value. However this barfs if I have multiple people with the same
DisplayName, as you can't have duplicate keys in a SortedList.

I know that I can override the IComparer that the SortedList uses for
comparisons, however, logistically I cannot think of a way to create
an IComparer that will be able to access the VALUES of the SortedList
collection. The problem is that I MUST supply the IComparer at
construction time of the SortedList; however the IComparer needs to
know about the SortedList so that when it is supplied with 2 keys to
sort, it can then access the values of the collection to work out
which comes before the other. And of course, I can't do something like
this -

SortedList sList = new SortedList(new MyComparer(sList));

for (hopefully) obvious reasons...

The other thing I tried was creating a "wrapper class" like this -

class SortedUserList : IComparer {
private SortedList userList = null;

public SortedList UserList {
get {
if (userList == null) {
userList = new SortedList(this);
}

return userList;
}
}

public SortedUserList() {
}

#region IComparer Members

public int Compare(object x, object y) {
string first = UserList[x] as string;
string second = UserList[y] as string;

return first.CompareTo(second);
}

#endregion
}

But this also didn't work - I got a Stack Overflow when I tried to add
the second user into the list.

I'm really hoping that there is a simple solution to this problem.

Thanks for your help,
gerrod
Nov 15 '05 #1
1 20033
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

No you can't just pass in a Comparator, because in SortedList, it is
automatically applied to the keys instead of the values, no matter what
you do (and that's the way it is supposed to work anyway...)

An easy way would be to preserve the link between the key and the value
yourself, e.g.: in a struct, like a short program below, and then make
it implement IComparable to sort it based on user names. Then, a simple
ArrayList will do from there (see below)

using System;
using System.Collections;

class MainClass
{
~ public static void Main(string[] args) {
~ ArrayList users = new ArrayList();

~ users.Add(new User(1000, "Set"));
~ users.Add(new User(1004, "List"));
~ users.Add(new User(1002, "Gerrod"));
~ users.Add(new User(1003, "Map"));

~ users.Sort();

~ foreach (User user in users) {
~ Console.WriteLine(user.Id + ", " + user.Name);
~ }
~ }
}

struct User : IComparable {
~ private long _id;
~ private string _name;

~ public User(long id, string name) {
~ _id = id;
~ _name = name;
~ }

~ public long Id {
~ get {
~ return _id;
~ }
~ }

~ public string Name {
~ get {
~ return _name;
~ }
~ }

~ public int CompareTo(object obj) {
~ if(obj == null) {
~ return 1;
~ }
~ User that = (User)obj;
~ return this._name.CompareTo(that._name);
~ }
}
gerrod wrote:

| Hi -
|
| Does anyone know a way to created a SortedList (in the
| System.Collections namespace) that will sort on VALUES instead of
| KEYS... ?
|
| The scenario is this - I have a SortedList containing key-value pairs
| of UserID - DisplayName for a whole bunch of user objects. The UserID
| is simply a long, the DisplayName is something like, "Jones, Bill". I
| want the SortedList to sort the names alphabetically, rather than by
| increasing order of UserIDs.
|
| The simple answer is to use the DisplayName as a key, and UserID as a
| value. However this barfs if I have multiple people with the same
| DisplayName, as you can't have duplicate keys in a SortedList.
|
| I know that I can override the IComparer that the SortedList uses for
| comparisons, however, logistically I cannot think of a way to create
| an IComparer that will be able to access the VALUES of the SortedList
| collection. The problem is that I MUST supply the IComparer at
| construction time of the SortedList; however the IComparer needs to
| know about the SortedList so that when it is supplied with 2 keys to
| sort, it can then access the values of the collection to work out
| which comes before the other. And of course, I can't do something like
| this -
|
| SortedList sList = new SortedList(new MyComparer(sList));
|
| for (hopefully) obvious reasons...
|
| The other thing I tried was creating a "wrapper class" like this -
|
| class SortedUserList : IComparer {
| private SortedList userList = null;
|
| public SortedList UserList {
| get {
| if (userList == null) {
| userList = new SortedList(this);
| }
|
| return userList;
| }
| }
|
| public SortedUserList() {
| }
|
| #region IComparer Members
|
| public int Compare(object x, object y) {
| string first = UserList[x] as string;
| string second = UserList[y] as string;
|
| return first.CompareTo(second);
| }
|
| #endregion
| }
|
| But this also didn't work - I got a Stack Overflow when I tried to add
| the second user into the list.
|
| I'm really hoping that there is a simple solution to this problem.
|
| Thanks for your help,
| gerrod
- --
Ray Hsieh (Djajadinata)
ray underscore usenet at yahoo dot com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQE/nIkiwEwccQ4rWPgRAqn+AJ402SGnegA2+hvAOFQf+3PvfI5yiQ CfYAk4
cXPzlQMWMVXcpDbSsNK103w=
=tjwy
-----END PGP SIGNATURE-----

Nov 15 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Johannes | last post: by
1 post views Thread by Vai2000 | last post: by
3 posts views Thread by Michael C | last post: by
6 posts views Thread by Jose Jarabo | last post: by
2 posts views Thread by Pekka | last post: by
6 posts views Thread by Antonio Paglia | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.