I have a SortedList filled with keys and values. When I try GetKey(index), I get my key, and when I try GetByIndex(index), I get my value. But when I try to use IndexOfKey() or ContainsKey(), I get the following error:

"Failed to compare two elements in the array."

I need to place each key/value element into a ComboBox (which I've been able to do), then set the selected item of the ComboBox to the element with a specific key, so I need find the index for that specific key, but everything I try gives me the above error.

Are your indicies of a type that have the ability to be directly compared? (like ints or strings)?

If not you must write an IComparer<your_index_object> method and pass it into the constructor of the sorted list.

Here's the MSDN for sorted list.
http://msdn.microsoft.com/en-us/library/system.collections.sortedlist.aspx

Both my key and value are assigned as objects, but are essentially both strings (well, keys are ints, but being read as strings from their source).
If I need an IComparer<index_object> method, can you explain how I'd go about that? Never used one before.

BTW, I have a 2nd SortedList doing basically the same thing, but my keys are sequential ints, so basically the same as the index of each item. This 2nd SortedList / combobox scenario works as expected, since I'm able to just use the index.

Edited 6 Years Ago by roachae: n/a

Can you post a small portion of your code so I can try and run it?

for IComparer you need a class (can be within the same namespace, not sure if that's what should be done with it though):

Say you have a class Person that has a public member variable of type int named year of birth and you wanted to use this as your key.

public class PersonComparer : IComparer<Person>
{  //don't select IComparable which is something a bit different
    //see the article below

    //Now normally with ints, we arrange them from highest to lowest
//but we want our sort by age, so we reverse the usual scheme for 
//returning 1 if the first value is greater than the second one, or if they 
//are equal and -1 if first is less than the second

public int Compare(Person A,Person B)  //must be compare as that's
//what the interface dictates
{
           if(A.Year < B.Year)   
                  return 1;
          
           if(A.Year > B.Year)
                   return -1;
           else
                    return 0;

}
}

Then back in your program where you defined your list:

PersonComparer pc = new PersonComparer(); //for obj1
SortedList<obj 1,obj 2> personlist = new SortedList<obj1,obj2> (pc);

Excellent ref with some more examples:
http://support.microsoft.com/kb/320727

Edited 6 Years Ago by jonsca: n/a

Can you post a small portion of your code so I can try and run it?

for IComparer you need a class (can be within the same namespace, not sure if that's what should be done with it though):

Say you have a class Person that has a public member variable of type int named year of birth and you wanted to use this as your key.

public class PersonComparer : IComparer<Person>
{  //don't select IComparable which is something a bit different
    //see the article below

    //Now normally with ints, we arrange them from highest to lowest
//but we want our sort by age, so we reverse the usual scheme for 
//returning 1 if the first value is greater than the second one, or if they 
//are equal and -1 if first is less than the second

public int Compare(Person A,Person B)  //must be compare as that's
//what the interface dictates
{
           if(A.Year < B.Year)   
                  return 1;
          
           if(A.Year > B.Year)
                   return -1;
           else
                    return 0;

}
}

Then back in your program where you defined your list:

PersonComparer pc = new PersonComparer(); //for obj1
SortedList<obj 1,obj 2> personlist = new SortedList<obj1,obj2> (pc);

Excellent ref with some more examples:
http://support.microsoft.com/kb/320727

I can show you some code, but it probably won't be easy to run it, since my SortedList is being filled by reading from a database on a Erlang-written server-side. Basically, as I said earlier, my SortedList's keys are ints, but read as strings from the database, and its values are strings... but both are assigned as objects. The combobox I'm using is within a DataGridViewComboboxCell and each item of the combobox is filled from the SortedList as follows:

for (int i = 0; i < mySortedList.Count; i++)
{
    myCell.Items.Add(Skin.Unparse(mySortedList.GetByIndex(i)));
}

The Skin.Unparse() routine written by a former fellow employee, which basically converts an object read from the Erlang server to a string. As I've said earlier, my combobox is being filled as it should be.

A sample of my keys and values are as follows:

Key Values
------- ------------------
"101" "\"Value 1\""
"102" "\"Value 2\""
"103" "\"Value 3\""
"201" "\"Value 4\""
"202" "\"Value 5\""

I'll try your suggestion with the IComparer and see what I can do. If there's any other ideas or thoughts you might have, let me know. Thanks.

Are you declaring a string and adding string variables to your list or are you running the function in the add? If you are working with strings, make sure what is passed is a string.
If it is receiving an object in the key that it can't figure out the order of, I'm surprised it even allows you to add it.
try casting it as string and add that.

I can show you some code, but it probably won't be easy to run it, since my SortedList is being filled by reading from a database on a Erlang-written server-side. Basically, as I said earlier, my SortedList's keys are ints, but read as strings from the database, and its values are strings... but both are assigned as objects. The combobox I'm using is within a DataGridViewComboboxCell and each item of the combobox is filled from the SortedList as follows:

for (int i = 0; i < mySortedList.Count; i++)
{
    myCell.Items.Add(Skin.Unparse(mySortedList.GetByIndex(i)));
}

The Skin.Unparse() routine written by a former fellow employee, which basically converts an object read from the Erlang server to a string. As I've said earlier, my combobox is being filled as it should be.

A sample of my keys and values are as follows:

Key Values
------- ------------------
"101" "\"Value 1\""
"102" "\"Value 2\""
"103" "\"Value 3\""
"201" "\"Value 4\""
"202" "\"Value 5\""

I'll try your suggestion with the IComparer and see what I can do. If there's any other ideas or thoughts you might have, let me know. Thanks.

Got it to work. Thanks for the help, jonsca.

This question has already been answered. Start a new discussion instead.