1

I have a string array like this:

string[] names = new string[] { "john", "paul", "ringo", "george", "janis" };

I want to sort this array using a custom criteria. It can't be alphabetical. It might be in this order: pgrj.

I've tried to implement a new IComparer, but inside the Compare() method I can't use string.Compare cause it would sort alphabetically and I don't want to do that.

The question is: How can I sort the names array in this order: pgrj ? In the 'j' case. Janis might be before John.

Thanks.

5
  • See this answer stackoverflow.com/questions/6984457/linq-complex-sorting/… Commented Aug 8, 2011 at 19:38
  • Is this custom order purely based on rearranging the alphabet? In other words, if "Janis" comes before "John", is that because "a" would come before "o", regardless of where it is in the word? Commented Aug 8, 2011 at 19:39
  • There are some good tips in these blog posts by Eric Lippert when dealing with custom sorting : bit.ly/piH3eu Commented Aug 8, 2011 at 19:41
  • Yes, it's purely based on rearranging the alphabet. I was wrong. I'll list all words of alphabet and rearrange it. The words array might be rearranged too. Commented Aug 8, 2011 at 20:02
  • I've already tried to use the StartsWith() inside the IComparer. But I can sort only using the first letter of each word. Commented Aug 8, 2011 at 20:03

2 Answers 2

2

I would make an array of the letters of the alphabet, in the order that they should be sorted. Let's call this array sort. You could then do something like

for (int i = 0; i < s1.Length; i++)
{
    int s1Value = sort.IndexOf(s1[i]);
    int s2Value = sort.IndexOf(s2[i]);

   if(s1Value > s2Value)
       return 1;

   if(s2Value > s1Value)
       return -1;
}

return 0;

Now a few disclaimers.

  1. I might have my -1 and 1 mixed up. I haven't looked at ICompare in a while and I forget which is which.
  2. This does not handle the two strings being different lengths.
  3. I have not tested this code.

You could improve on this by making a custom class to assign a weight to each character.

class CustomAlphabetSort
{
     public char Character { get; set; }
     public int Weight { get; set; }
}

From here you can sum of the value for each letter of a string and do the comparison that way. It might be a little more complex than your situation requires

Sign up to request clarification or add additional context in comments.

1 Comment

Nice. I'll try increase this idea.
2
void Main()
{
    string[] names = new string[] { "john", "paul", "ringo", "george", "janis" };
    var reorderedNames = names.OrderByDescending(x => x, new MyComparer());
}

class MyComparer : IComparer<string>{

    int IComparer<string>.Compare(string s1, string s2){

        char l1 = s1[0];
        char l2 = s2[0];
        int ret;

        switch(l1){

            case 'g':   if(l2 == 'p'){
                            return -1;
                        }
                        else{
                            goto default;
                        }
            case 'r':   if(l2 == 'p' || l2 == 'g'){
                            return -1;
                        }
                        else{
                            goto default; 
                        }
            case 'j':   if(l2 == 'p' || l2 == 'g' || l2 == 'r'){
                            return -1;
                        }
                        else{
                            goto default;
                        }
            default:    ret = (l2 != l1) ?  1 : s1.CompareTo(s2); return ret;   
        }
        return ret;
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.