Search code examples
c#sortingicomparable

Sorting a list of names with first/last name and age C#


I want to sort the names on this list first by age (which I have done so far), but I was wondering how I could then sort these names again by last name before printing to a new file. For example if I have 5 people that are 20 years old with different last names, how could I make sure those 5 people are in ascending alphabetical order?

class Person : IComparable
{
    string vorname;
    string nachname;
    int age;

    public Person(string vorname, string nachname, int age)
    {
        this.age = age;
        this.nachname = nachname;
        this.vorname = vorname;
    }

    public int CompareTo(object obj)
    {
        Person other = (Person)obj;
        int a = this.age - other.age;

        if (a != 0)
        {
            return -a;
        }
        else
        {
            return age.CompareTo(other.age);
        }
    }

    public override string ToString()
    {
        return vorname + " " + nachname + "\t" + age;
    }        
}

class Program
{
    static void Main(string[] args)
    {
        Person[] peeps = new Person[20];

        try
        {
            StreamReader sr = new StreamReader("inputNames.txt");

            int count = 0;

            while (!sr.EndOfStream)
            {
                string data = sr.ReadLine();
                Console.WriteLine();
                string[] info = data.Split(',');
                peeps[count] = new Person(info[0], info[1], int.Parse(info[2]));

                count++;
            }
            Array.Sort(peeps);
            sr.Close();
        }
        catch(FileNotFoundException e)
        {
            Console.WriteLine(e.Message);
        }

        StreamWriter sw = new StreamWriter("outputNames.txt");

        Console.WriteLine();
        foreach (Person p in peeps)
        {
            Console.WriteLine(p);
            sw.WriteLine(p);
        }
        sw.Close();
    }
}

Solution

  • Linq is your friend. You can re-write all that code in 1 line:

    peeps.OrderBy(x => x.Age).ThenBy(x => x.LastName);
    

    That's all there is to it :). You can get rid of all that IComparable junk, that's old school.

    EDIT: for IComparable, you can do:

        public int CompareTo(object obj)
        {
            Person other = (Person)obj;
    
            if (age < other.age)
                return -1;
    
            if (String.Compare(vorname, other.vorname) < 0)
                return -1;
    
            return 1;
        }
    

    Seems to work for my quick testing, but test it more :).