digitalmars.D.learn - Array.sort understanding need
- jicman <jicman_member pathlink.com> Aug 05 2005
- Vathix <chris dprogramming.com> Aug 05 2005
- jicman <jicman_member pathlink.com> Aug 05 2005
- Vathix <chris dprogramming.com> Aug 05 2005
- jicman <jicman_member pathlink.com> Aug 05 2005
Greetings!
Imagine this code,
|import std.string;
|import std.stdio;
|class DAEError
|{
| char[] name = "";
| int Count = 0;
|}
|
|void main()
|{
| DAEError Err[];
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "A";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "B";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "C";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "D";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "a";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "b";
| Err[Err.length - 1].Count++;
| Err.length = Err.length + 1;
| Err[Err.length - 1] = new DAEError();
| Err[Err.length - 1].name = "c";
| Err[Err.length - 1].Count++;
| Err = Err.sort;
| foreach (int error, DAEError e; Err)
| writefln(Err[error].name, " ", toString(Err[error].Count));
|}
If I compile this code and run it, I get,
jic 11:01:19-> ./sort
c 1
b 1
a 1
D 1
C 1
B 1
A 1
This is not what I expected at all. But, I must say that the sort function does
work great with char[][] arrays. But, on this one, I would expect to have .name
and then, .Count be the sorting keys, in that order. Am I crazy or just don't
understand sort?
thanks,
josé
Aug 05 2005
On Fri, 05 Aug 2005 11:11:13 -0400, jicman <jicman_member pathlink.com> wrote:Greetings! Imagine this code, |import std.string; |import std.stdio; |class DAEError |{ | char[] name = ""; | int Count = 0; |}
Add opCmp() and opEquals() to the class and tell it how to sort.
Aug 05 2005
Vathix says...On Fri, 05 Aug 2005 11:11:13 -0400, jicman <jicman_member pathlink.com> wrote:Greetings! Imagine this code, |import std.string; |import std.stdio; |class DAEError |{ | char[] name = ""; | int Count = 0; |}
Add opCmp() and opEquals() to the class and tell it how to sort.
Thanks. However, I have been looking at this page, http://www.digitalmars.com/d/operatoroverloading.html and pardon my D ignorance and/or c, but I have never used OpCmp() nor opEquals(). I have gone into the web and search for "sorting array opCmp() opEquals()" and found a few pages, but none really shows any examples. Will anyone be willing to point me to an example that uses what Vathix has suggested? Thanks again. josé
Aug 05 2005
import std.stdio, std.string;
class Foo
{
char[] str;
int num;
this(char[] str, int num)
{
this.str = str;
this.num = num;
}
override char[] toString()
{
return format("'%s' %d", str, num);
}
override int opCmp(Object obj) // Override from Object.
{
Foo f;
f = cast(Foo)obj;
if(f)
return opCmp(f); // Use opCmp(Foo).
assert(0); // Wrong type.
}
int opCmp(Foo f)
{
int result;
result = std.string.cmp(str, f.str);
if(!result) // If match, compare num`s.
result = num - f.num;
return result;
}
override int opEquals(Object obj) // Override from Object.
{
Foo f;
f = cast(Foo)obj;
if(f)
return opEquals(f); // Use opEquals(Foo).
assert(0); // Wrong type.
}
int opEquals(Foo f)
{
int result;
result = str != f.str;
if(!result) // If match, compare num`s.
result = num - f.num;
return result;
}
}
int main()
{
Foo[8] fs;
fs[0] = new Foo("foo", 3);
fs[1] = new Foo("foo", 1);
fs[2] = new Foo("candy", 4);
fs[3] = new Foo("foo", 5);
fs[4] = new Foo("gum", 5);
fs[5] = new Foo("zoo", 9);
fs[6] = new Foo("bar", 9);
fs[7] = new Foo("fun", 88);
fs.sort;
foreach(Foo f; fs)
{
writefln("%s", f.toString());
}
return 0;
}
Aug 05 2005
Vathix says...import std.stdio, std.string; class Foo { char[] str; int num; this(char[] str, int num) { this.str = str; this.num = num; } override char[] toString() { return format("'%s' %d", str, num); } override int opCmp(Object obj) // Override from Object. { Foo f; f = cast(Foo)obj; if(f) return opCmp(f); // Use opCmp(Foo). assert(0); // Wrong type. } int opCmp(Foo f) { int result; result = std.string.cmp(str, f.str); if(!result) // If match, compare num`s. result = num - f.num; return result; } override int opEquals(Object obj) // Override from Object. { Foo f; f = cast(Foo)obj; if(f) return opEquals(f); // Use opEquals(Foo). assert(0); // Wrong type. } int opEquals(Foo f) { int result; result = str != f.str; if(!result) // If match, compare num`s. result = num - f.num; return result; } } int main() { Foo[8] fs; fs[0] = new Foo("foo", 3); fs[1] = new Foo("foo", 1); fs[2] = new Foo("candy", 4); fs[3] = new Foo("foo", 5); fs[4] = new Foo("gum", 5); fs[5] = new Foo("zoo", 9); fs[6] = new Foo("bar", 9); fs[7] = new Foo("fun", 88); fs.sort; foreach(Foo f; fs) { writefln("%s", f.toString()); } return 0; }
Any questions? :-) Thank you. I appreciate it very much. Never done this, so this example is perfect. josé
Aug 05 2005








jicman <jicman_member pathlink.com>