classical312
classical312

Reputation: 185

Lexicographically sort C#

I have this code for sorting strings:

 class Program
{
    static void Main()
    {

        int x = Convert.ToInt32(Console.ReadLine());
        List<string> sampleList = new List<string>();

        for (int i=0; i<x; i++)
        {
            string word = Console.ReadLine();
            sampleList.Add(word);
        }


        foreach (string s in SortByLength(sampleList))
        {
            Console.Write(s);
        }
        Console.ReadLine();
    }

    static IEnumerable<string> SortByLength(IEnumerable<string> e)
    {
        // Use LINQ to sort the array received and return a copy.
        var sorted = from s in e
                     orderby s.Length descending
                     select s;
        return sorted;
    }
}

This code sorting strings by length, how can I do that by length and lexicographically ?

Example

//Input
4
abba
abacaba
bcd
er

//Output
abacabaabbabcder

In this case work fine, but when I have

//Input
5
abba
ebacaba
bcd
er
abacaba

//Output
ebacabaabacabaabbabcder

My first string is ebacaba which is wrong.

Upvotes: 5

Views: 19828

Answers (3)

Ian
Ian

Reputation: 30813

Edit:

By default, the non-char is lexically smaller than the char, thus, you can exploit this and omit ThenBy but will still get the same result like this (Credit goes to Matthew Watson):

string str = "abba ebacaba bcd er abacaba output ebacabaabacabaabbabcder";
string[] strs = str.Split(' ').OrderBy(x => x).ToArray(); //same result, but shorter

Original:

Use OrderBy and also ThenBy

string str = "abba ebacaba bcd er abacaba output ebacabaabacabaabbabcder";
string[] strs = str.Split(' ').OrderBy(x => x).ThenBy(x => x.Length).ToArray();

You will get:

abacaba //aba is earlier than abb
abba
bcd
ebacaba
ebacabaabacabaabbabcder
er

Upvotes: 6

Thomas Ayoub
Thomas Ayoub

Reputation: 29451

Change your function t:

static IEnumerable<string> SortByLength(IEnumerable<string> e)
{
        // Use LINQ to sort the array received and return a copy.
        var sorted = from s in e
                     orderby s.Length descending, s
                     select s;
        return sorted;
    }

Which will output:

abacabaabbabcder
abacaba
output
abb
bcd
edr

When used with new List<string>{"abb", "abacaba", "bcd", "edr", "output", "abacabaabbabcder"}

Because it will order by s.Length, then by s (lexical order)

Upvotes: 2

Quentin Roger
Quentin Roger

Reputation: 6538

You can use thenby :

static IEnumerable<string> SortByLength(IEnumerable<string> e)
{
    // Use LINQ to sort the array received and return a copy.
    var sorted = e.OrderByDescending(s=>s.Length).ThenBy(r=>r);                 
    return sorted;
}

Upvotes: 4

Related Questions