|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Sorting Array using IcomparableI have a class that will sort a FileInfo array by date. public class CompareFileInfoByDate : IComparer { public int Compare(object x, object y) { FileInfo File1 = default(FileInfo); FileInfo File2 = default(FileInfo); File1 = (FileInfo)x; File2 = (FileInfo)y; return DateTime.Compare(File1.LastWriteTime, File2.LastWriteTime); } } This works fine. I call it like: Array.Sort(strFiles, new CompareFileInfoByDate()); Where strFiles is an array of FileInfo objects. This will sort by date in ascending order. I pass it the class but not the method to use. How does it know what to use. The reason I am asking is that I need to sort this in ascending and descending order. One way around that is to just create another method exactly the same but just reverse the return statement to look like: return DateTime.Compare(File2.LastWriteTime, File1.LastWriteTime); This works fine. Can I have another method in class that named - CompareReverse? If so, how would I tell Array.Sort to use the CompareReverse? I could write another whole class but it seems like overkill if I can just use the same class for both methods. I looked at Array.Reverse, but it won't take an IComparer interface. Thanks, Tom
Show quote
Hide quote
"tshad" <t***@pdsa.com> wrote in message Consider giving your comparison class a constructor that takes a sort news:OcLjl857JHA.4132@TK2MSFTNGP06.phx.gbl... >I have a couple of issues here stemming from the same code. > > I have a class that will sort a FileInfo array by date. > > public class CompareFileInfoByDate : IComparer > { > public int Compare(object x, object y) > { > FileInfo File1 = default(FileInfo); > FileInfo File2 = default(FileInfo); > > File1 = (FileInfo)x; > File2 = (FileInfo)y; > > return DateTime.Compare(File1.LastWriteTime, > File2.LastWriteTime); > } > } > > This works fine. > > I call it like: > > Array.Sort(strFiles, new CompareFileInfoByDate()); > > Where strFiles is an array of FileInfo objects. > > This will sort by date in ascending order. > > I pass it the class but not the method to use. How does it know what to > use. > > The reason I am asking is that I need to sort this in ascending and > descending order. > > One way around that is to just create another method exactly the same but > just reverse the return statement to look like: > > return DateTime.Compare(File2.LastWriteTime, > File1.LastWriteTime); > > This works fine. > > Can I have another method in class that named - CompareReverse? > > If so, how would I tell Array.Sort to use the CompareReverse? > > I could write another whole class but it seems like overkill if I can just > use the same class for both methods. > > I looked at Array.Reverse, but it won't take an IComparer interface. > > Thanks, > > Tom > direction argument. Save the direction value in a private field and test it in the Compare function. HTH, Tom Dacon Dacon Software Consulting I will try that.
What about the first part of the question? In the class, can you only have one method that must be named Compare? Thanks, Tom Show quoteHide quote "Tom Dacon" <tdacon@community.nospam> wrote in message news:egJLhG67JHA.1416@TK2MSFTNGP04.phx.gbl... > > "tshad" <t***@pdsa.com> wrote in message > news:OcLjl857JHA.4132@TK2MSFTNGP06.phx.gbl... >>I have a couple of issues here stemming from the same code. >> >> I have a class that will sort a FileInfo array by date. >> >> public class CompareFileInfoByDate : IComparer >> { >> public int Compare(object x, object y) >> { >> FileInfo File1 = default(FileInfo); >> FileInfo File2 = default(FileInfo); >> >> File1 = (FileInfo)x; >> File2 = (FileInfo)y; >> >> return DateTime.Compare(File1.LastWriteTime, >> File2.LastWriteTime); >> } >> } >> >> This works fine. >> >> I call it like: >> >> Array.Sort(strFiles, new CompareFileInfoByDate()); >> >> Where strFiles is an array of FileInfo objects. >> >> This will sort by date in ascending order. >> >> I pass it the class but not the method to use. How does it know what to >> use. >> >> The reason I am asking is that I need to sort this in ascending and >> descending order. >> >> One way around that is to just create another method exactly the same but >> just reverse the return statement to look like: >> >> return DateTime.Compare(File2.LastWriteTime, >> File1.LastWriteTime); >> >> This works fine. >> >> Can I have another method in class that named - CompareReverse? >> >> If so, how would I tell Array.Sort to use the CompareReverse? >> >> I could write another whole class but it seems like overkill if I can >> just use the same class for both methods. >> >> I looked at Array.Reverse, but it won't take an IComparer interface. >> >> Thanks, >> >> Tom >> > > Consider giving your comparison class a constructor that takes a sort > direction argument. Save the direction value in a private field and test > it in the Compare function. > > HTH, > Tom Dacon > Dacon Software Consulting > "tshad" <t***@pdsa.com> wrote in message Not at all, Tom. While if the class implements the IComparer interface it news:OYfdlu67JHA.4116@TK2MSFTNGP04.phx.gbl... >I will try that. > > What about the first part of the question? > > In the class, can you only have one method that must be named Compare? > must have one and only one Compare method, the class can have any other methods or properties that you want. Tom Dacon Dacon Software Consulting
Show quote
Hide quote
"Tom Dacon" <tdacon@community.nospam> wrote in message So then when I run:news:ua742267JHA.5932@TK2MSFTNGP03.phx.gbl... > > "tshad" <t***@pdsa.com> wrote in message > news:OYfdlu67JHA.4116@TK2MSFTNGP04.phx.gbl... >>I will try that. >> >> What about the first part of the question? >> >> In the class, can you only have one method that must be named Compare? >> > > Not at all, Tom. While if the class implements the IComparer interface it > must have one and only one Compare method, the class can have any other > methods or properties that you want. > Array.Sort(strFiles, new CompareFileInfoByDate()); It will instantiate the class (or actually since being passed with "new" in the parameter it will instantiate automatically and pass the object to Array) then it will call Compare (many times). So I could not have a CompareReverse in there unless Compare called CompareReverse based on a passed flag. Now I wouldn't do that because I can just do an if test on a memory variable and do 2 different returns. The way I ended up doing it was (which was your suggestion): public class CompareFileInfoByDate : IComparer { private bool mboolForward; public CompareFileInfoByDate() { Forward = true; } public CompareFileInfoByDate(bool forward) { Forward = forward; } public int Compare(object x, object y) { FileInfo File1 = default(FileInfo); FileInfo File2 = default(FileInfo); File1 = (FileInfo)x; File2 = (FileInfo)y; if(Forward) return DateTime.Compare(File1.LastWriteTime, File2.LastWriteTime); else return DateTime.Compare(File2.LastWriteTime, File1.LastWriteTime); } public bool Forward { get { return mboolForward; } set { mboolForward = value; } } } Thanks, Tom Show quoteHide quote > Tom Dacon > Dacon Software Consulting > >
Show quote
Hide quote
"tshad" <t***@pdsa.com> wrote in message Just fine, Tom. The Forward property could just as well have been private, news:%23s9T$dD8JHA.728@TK2MSFTNGP05.phx.gbl... > > "Tom Dacon" <tdacon@community.nospam> wrote in message > news:ua742267JHA.5932@TK2MSFTNGP03.phx.gbl... >> >> "tshad" <t***@pdsa.com> wrote in message >> news:OYfdlu67JHA.4116@TK2MSFTNGP04.phx.gbl... >>>I will try that. >>> >>> What about the first part of the question? >>> >>> In the class, can you only have one method that must be named Compare? >>> >> >> Not at all, Tom. While if the class implements the IComparer interface it >> must have one and only one Compare method, the class can have any other >> methods or properties that you want. >> > So then when I run: > > Array.Sort(strFiles, new CompareFileInfoByDate()); > > It will instantiate the class (or actually since being passed with "new" > in the parameter it will instantiate automatically and pass the object to > Array) then it will call Compare (many times). > > So I could not have a CompareReverse in there unless Compare called > CompareReverse based on a passed flag. > > Now I wouldn't do that because I can just do an if test on a memory > variable and do 2 different returns. > > The way I ended up doing it was (which was your suggestion): > > public class CompareFileInfoByDate : IComparer > { > private bool mboolForward; > > public CompareFileInfoByDate() > { > Forward = true; > } > > public CompareFileInfoByDate(bool forward) > { > Forward = forward; > } > > public int Compare(object x, object y) > { > FileInfo File1 = default(FileInfo); > FileInfo File2 = default(FileInfo); > > File1 = (FileInfo)x; > File2 = (FileInfo)y; > > if(Forward) > return DateTime.Compare(File1.LastWriteTime, > File2.LastWriteTime); > else > return DateTime.Compare(File2.LastWriteTime, > File1.LastWriteTime); > } > > public bool Forward > { > get { return mboolForward; } > set { mboolForward = value; } > } > > } > > Thanks, > > Tom >> Tom Dacon >> Dacon Software Consulting >> >> > > the way you're using it, but it doesn't matter much. Tom On Wed, 17 Jun 2009 15:58:34 -0700, tshad <t***@pdsa.com> wrote:
> [...] Because it uses the IComparer implementation, and that method is the > I pass it the class but not the method to use. How does it know what to > use. implementation. > The reason I am asking is that I need to sort this in ascending and Sure. You can put whatever methods into the class you want. But it won't > descending order. > > One way around that is to just create another method exactly the same but > just reverse the return statement to look like: > > return DateTime.Compare(File2.LastWriteTime, > File1.LastWriteTime); > > This works fine. > > Can I have another method in class that named - CompareReverse? be used in the comparison. > If so, how would I tell Array.Sort to use the CompareReverse? You don't. It can only call Compare(), because that's the one method in IComparer and the IComparer implementation is the only thing Array.Sort() cares about. > I could write another whole class but it seems like overkill if I can Seems to me the simplest approach is to use a multiplier in the class, and > just > use the same class for both methods. then initialize the class appropriate, depending on whether you want it to do ascending or descending: public class CompareFileInfoByDate : IComparer { public CompareFileInfoByDate(bool fAscending) { _faction = fAscending ? 1 : -1; } private int _factor; public int Compare(object x, object y) { FileInfo File1 = (FileInfo)x; FileInfo File2 = (FileInfo)y; return _factor * DateTime.Compare(File1.LastWriteTime, File2.LastWriteTime); } } > I looked at Array.Reverse, but it won't take an IComparer interface. Why would it? All it does is reverse the existing contents, whether they are sorted or not. You could, of course, always sort ascending, and then reverse the results if you want descending. But it's more efficient to just sort in the order you want. Pete tshad schrieb:
Show quoteHide quote > I have a class that will sort a FileInfo array by date. because you pass it an object that implements IComparer,> > public class CompareFileInfoByDate : IComparer > { > public int Compare(object x, object y) > { > File1 = (FileInfo)x; > File2 = (FileInfo)y; > > return DateTime.Compare(File1.LastWriteTime, > File2.LastWriteTime); > } > } > > This works fine. > > I call it like: > > Array.Sort(strFiles, new CompareFileInfoByDate()); > > Where strFiles is an array of FileInfo objects. > > This will sort by date in ascending order. > > I pass it the class but not the method to use. How does it know what to > use. so it will call its Compare-method for all pairs of FileInfo within your array, until it's sorted. > The reason I am asking is that I need to sort this in ascending and Yes but it won't be called for sorting, since Array.Sort only will look> descending order. > Can I have another method in class that named - CompareReverse? for and execute "IComparer.Compare" ignoring all the remaining methods and members of the object. A very good idea is, as Tom said, to pass a Ascending/Descending flag in the c'tor and to evaluate it withing the Compare-call. For example: //call for descending sort Array.Sort(strFiles, new CompareFileInfoByDate(true)); //class public class CompareFileInfoByDate { private int _factor = 1; public CompareFileInfoByDate (bool isDescending) { if (isDescending) _factor = -1; /* this will reverse the result of DateTime.Compare */ } public int Compare(object x, object y) { File1 = (FileInfo)x; File2 = (FileInfo)y; return _factor * DateTime.Compare(File1.LastWriteTime, File2.LastWriteTime); } } Alex "tshad" <t***@pdsa.com> wrote in message <snip>news:OcLjl857JHA.4132@TK2MSFTNGP06.phx.gbl... >I have a couple of issues here stemming from the same code. > > One way would be to pass a value in to the constructor of your IComparer > Can I have another method in class that named - CompareReverse? > > If so, how would I tell Array.Sort to use the CompareReverse? > that tells it which implementation method to use. Perhaps an enum. enum MYCOMPARE {LASTWRITE, REVERSE} private MYCOMPARE comparetype public int Compare(object x, object y) { FileInfo File1 = (FileInfo)x; FileInfo File2= (FileInfo)y; if(comparetype == MYCOMPARE.LASTWRITE) return CompareLast(File1, File2); else if (comparetype == MYCOMPARE.REVERSE) return CompareReverse(File1, File2); } You could also use delegates Sorry about the quick and dirty code...I am running late, but it should give you enough to figure the rest out. Bill
Other interesting topics
solve c# problems
MemoryAccessViolationException and multimedia timer problem Aren't All MD5 Hashes the Same? Image Implementing IDisposable on factory pattern objects Convert number to Excel column name StatusStrip wiping out 2nd label Clearing a Collection WPF Canvas: How to find its children's location? How to determine if a string is Base64 encoded or not? |
|||||||||||||||||||||||