IComparer, Compare, CompareTo for multiple comparisons for Sort inArray and List

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • raylopez99

    IComparer, Compare, CompareTo for multiple comparisons for Sort inArray and List

    This is an example of using multiple comparison criteria for IComparer/
    Compare/CompareTo for List<and Array.

    Adapted from David Hayden's tutorial found on the net, but he used
    ArrayList so the format was different.

    Basically you can sort a class having members LastName (string),
    FirstName (string) and Age (int) according to whether you want to sort
    by Last Name, First Name or Age, using the .Sort function

    Question for the group: a suggestion in Albahari C#3 in a Nutshell
    says you can, as an alternative to calling Sort, use LINQ's "OrderBy"
    and "ThenBy" operators. Unlike Array.Sort or List.Sort, the LINQ
    operators don't alter the original array or list, but instead emit the
    sorted result in a fresh IEnumerable<Tse quence.

    Any idea on how this can be done here? Remember, the
    "strings" (LastName, FirstName) and "int" (Age) are stored inside a
    class here, so it might be hard to do, since it seems to me LINQ
    queries require something like string [] FirstName = {"Tom", "Dick",
    "Harry"}; outside a class, rather than having the variables inside a
    class as here.

    If there's an easy way to use Linq, please post the complete code
    otherwise just a hint or pseudocode.

    Thanks

    RL


    // September 30, 2008
    //adapted from David Hayden [MVP C#] tutorial on net
    // in Hayden an ArrayList rather than a List was used
    // so the format was slightly different than here

    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;

    namespace console1
    {
    class Program
    {
    static void Main(string[] args)
    {

    List<PersonPers onList = new List<Person>();
    PersonList.Add( new Person("ray", "lopez", 38));
    PersonList.Add( new Person("zoe", "smith", 28));
    PersonList.Add( new Person("nue", "mather", 58));

    PersonComparer myPersonCompare r = new PersonComparer( );

    myPersonCompare r.ComparisonMet hod =
    PersonComparer. ComparisonType. Age;
    PersonList.Sort (myPersonCompar er);
    foreach (Person p in PersonList) Console.Write(p .LastName
    + "|");
    // works, sort by age

    Console.WriteLi ne("");
    myPersonCompare r.ComparisonMet hod =
    PersonComparer. ComparisonType. LastName;
    PersonList.Sort (myPersonCompar er);
    foreach (Person p in PersonList) Console.Write(p .LastName
    + "|");
    //works, sort by last name

    Console.WriteLi ne("");
    myPersonCompare r.ComparisonMet hod =
    PersonComparer. ComparisonType. FirstName;
    PersonList.Sort (myPersonCompar er);
    foreach (Person p in PersonList) Console.Write(p .LastName
    + "|");
    // works, sort by first name

    // IComparer works for Array too

    Person[] personArray = new Person[]{new Person("ray",
    "lopez", 38), new Person("zoe", "smith", 28),new Person("nue",
    "mather", 58)};
    Array.Sort(pers onArray, myPersonCompare r);
    foreach (Person p in personArray) Console.Write(p .LastName
    + "!");
    Console.WriteLi ne("");
    myPersonCompare r.ComparisonMet hod =
    PersonComparer. ComparisonType. Age;
    Array.Sort(pers onArray, myPersonCompare r);
    foreach (Person p in personArray) Console.Write(p .LastName
    + "!!");
    Console.WriteLi ne("\n");
    }
    }
    }
    ///////////////////////////
    /*
    * smith|lopez|mat her| //<--List is sorted by Age
    lopez|mather|sm ith| //<--Sorted by Last Name
    mather|lopez|sm ith| //<--Sorted by First name
    mather!lopez!sm ith! //<--now for an array, rather than
    list, also works, sort by FirstName
    smith!!lopez!!m ather!! <--sort array by age
    Press any key to continue . . .
    * */
    ////////////////////////////////////////////
    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnost ics;

    namespace console1
    {
    class Person
    {
    public string LastName;
    public int Age;
    public string FirstName;

    public Person(string fn, string ln, int age)
    {
    LastName = ln;
    FirstName = fn;
    Age = age;
    }

    public int CompareTo(Perso n p2, PersonComparer. ComparisonType
    myCType)
    {
    switch (myCType)
    {
    case PersonComparer. ComparisonType. Age:
    return Age.CompareTo(p 2.Age);
    case PersonComparer. ComparisonType. LastName:
    return LastName.Compar eTo(p2.LastName );
    default:
    return FirstName.Compa reTo(p2.FirstNa me);
    }
    }

    }

    class PersonComparer : IComparer<Perso n>
    {
    public enum ComparisonType
    { FirstName = 1, LastName = 2, Age = 3 }
    private ComparisonType _comparisonType ;
    public ComparisonType ComparisonMetho d
    {
    get { return _comparisonType ; }
    set { _comparisonType = value; }
    }

    public int Compare(Person x, Person y)
    {
    Person p1;
    Person p2;
    if (x is Person) p1 = x as Person;
    else
    throw new ArgumentExcepti on("Object not type Person");
    if (y is Person) p2 = y as Person;
    else
    throw new ArgumentExcepti on("Object not type Person");
    return p1.CompareTo(p2 ,_comparisonTyp e);

    }
    } } ////////////////////

  • Family Tree Mike

    #2
    Re: IComparer, Compare, CompareTo for multiple comparisons for Sort in Array and List

    There is no requirement that the query results be of strings. I think the
    following example addresses what you are asking, but if not, please clarify.
    It orders the people by age, then lastname, then firstname.

    var ages = from p in PersonList orderby p.Age, p.LastName, p.FirstName
    select p;
    foreach (Person p in ages)
    Console.Out.Wri teLine(p.LastNa me + " " + p.FirstName + " " + p.Age);
    Console.In.Read Line();

    "raylopez99 " <raylopez99@yah oo.comwrote in message
    news:6cc0b271-0fe6-4f43-a7c8-bb0201c9553f@y3 8g2000hsy.googl egroups.com...
    Question for the group: a suggestion in Albahari C#3 in a Nutshell
    says you can, as an alternative to calling Sort, use LINQ's "OrderBy"
    and "ThenBy" operators. Unlike Array.Sort or List.Sort, the LINQ
    operators don't alter the original array or list, but instead emit the
    sorted result in a fresh IEnumerable<Tse quence.
    >
    Any idea on how this can be done here? Remember, the
    "strings" (LastName, FirstName) and "int" (Age) are stored inside a
    class here, so it might be hard to do, since it seems to me LINQ
    queries require something like string [] FirstName = {"Tom", "Dick",
    "Harry"}; outside a class, rather than having the variables inside a
    class as here.
    >
    If there's an easy way to use Linq, please post the complete code
    otherwise just a hint or pseudocode.
    >
    >

    Comment

    • raylopez99

      #3
      Re: IComparer, Compare, CompareTo for multiple comparisons for Sortin Array and List

      On Sep 29, 7:26 pm, "Family Tree Mike"
      <FamilyTreeM... @ThisOldHouse.c omwrote:
       I think the
      following example addresses what you are asking, but if not, please clarify.
      It orders the people by age, then lastname, then firstname.
      Yes, it worked. That was deceptively easy; it makes me wonder why
      even bother with IComparer, unless you want a permanent newly sorted
      array or list.

      Thanks, FTM, you're a real programmer.

      RL

      Comment

      • =?Utf-8?B?RmFtaWx5IFRyZWUgTWlrZQ==?=

        #4
        Re: IComparer, Compare, CompareTo for multiple comparisons for Sor

        There is still good reason to impliment IComparer etc for a library class
        intended for use in other systems. After all, the other system developer may
        not know LINQ, or just may choose other mechanisms. But in a single
        developer environment, you may be right.

        "raylopez99 " wrote:
        >
        Yes, it worked. That was deceptively easy; it makes me wonder why
        even bother with IComparer, unless you want a permanent newly sorted
        array or list.
        >

        Comment

        Working...