Thread overview
Array.sort understanding need
Aug 05, 2005
jicman
Aug 05, 2005
Vathix
Aug 05, 2005
jicman
Aug 05, 2005
Vathix
Aug 05, 2005
jicman
August 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é


August 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.
August 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é


August 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;
}
August 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é