472,127 Members | 2,043 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,127 software developers and data experts.

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<Tsequence.

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.Collections.Generic;
using System.Linq;
using System.Text;

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

List<PersonPersonList = 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 myPersonComparer = new PersonComparer();

myPersonComparer.ComparisonMethod =
PersonComparer.ComparisonType.Age;
PersonList.Sort(myPersonComparer);
foreach (Person p in PersonList) Console.Write(p.LastName
+ "|");
// works, sort by age

Console.WriteLine("");
myPersonComparer.ComparisonMethod =
PersonComparer.ComparisonType.LastName;
PersonList.Sort(myPersonComparer);
foreach (Person p in PersonList) Console.Write(p.LastName
+ "|");
//works, sort by last name

Console.WriteLine("");
myPersonComparer.ComparisonMethod =
PersonComparer.ComparisonType.FirstName;
PersonList.Sort(myPersonComparer);
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(personArray, myPersonComparer);
foreach (Person p in personArray) Console.Write(p.LastName
+ "!");
Console.WriteLine("");
myPersonComparer.ComparisonMethod =
PersonComparer.ComparisonType.Age;
Array.Sort(personArray, myPersonComparer);
foreach (Person p in personArray) Console.Write(p.LastName
+ "!!");
Console.WriteLine("\n");
}
}
}
///////////////////////////
/*
* smith|lopez|mather| //<--List is sorted by Age
lopez|mather|smith| //<--Sorted by Last Name
mather|lopez|smith| //<--Sorted by First name
mather!lopez!smith! //<--now for an array, rather than
list, also works, sort by FirstName
smith!!lopez!!mather!! <--sort array by age
Press any key to continue . . .
* */
////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

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(Person p2, PersonComparer.ComparisonType
myCType)
{
switch (myCType)
{
case PersonComparer.ComparisonType.Age:
return Age.CompareTo(p2.Age);
case PersonComparer.ComparisonType.LastName:
return LastName.CompareTo(p2.LastName);
default:
return FirstName.CompareTo(p2.FirstName);
}
}

}

class PersonComparer : IComparer<Person>
{
public enum ComparisonType
{ FirstName = 1, LastName = 2, Age = 3 }
private ComparisonType _comparisonType;
public ComparisonType ComparisonMethod
{
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 ArgumentException("Object not type Person");
if (y is Person) p2 = y as Person;
else
throw new ArgumentException("Object not type Person");
return p1.CompareTo(p2,_comparisonType);

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

Sep 29 '08 #1
3 10444
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.WriteLine(p.LastName + " " + p.FirstName + " " + p.Age);
Console.In.ReadLine();

"raylopez99" <ra********@yahoo.comwrote in message
news:6c**********************************@y38g2000 hsy.googlegroups.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<Tsequence.

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.

Sep 30 '08 #2
On Sep 29, 7:26*pm, "Family Tree Mike"
<FamilyTreeM...@ThisOldHouse.comwrote:
*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
Sep 30 '08 #3
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.
Sep 30 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Tom | last post: by
3 posts views Thread by Cybertof | last post: by
2 posts views Thread by Arulraja | last post: by
4 posts views Thread by CodeRazor | last post: by
6 posts views Thread by Robert Robbins | last post: by
10 posts views Thread by INeedADip | last post: by
10 posts views Thread by Tony | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.