Thread overview
custom opCmp for array sort
Nov 28, 2008
New
Nov 28, 2008
New
Nov 28, 2008
Kagamin
Nov 29, 2008
Gide Nwawudu
Dec 01, 2008
New
Dec 01, 2008
Bill Baxter
Dec 03, 2008
bearophile
November 28, 2008
Hello,

I originally posted this question to the wrong group, I am trying here as suggested.

I am new with D and am stuck with something I hope somebody can help me with it. I am trying sort an array of paths which can take the two following forms:

/usr                ---> normal path
/bin=/other/bin     ---> a symlink

When I sort these paths, in the case of symlinks I want to ignore the right hand side and I just use the path before the "=" sign.

The array docs for DMD 2.0, say that can create a structure and create a opCmp function to cutomise the way sort works. I have tried this but calling .sort does not seem to pick-up my custom opCmp.

Any help would be very appreciated. I am including the code below

Thanks a lot
--------------------------------------------------------------------
Code cleaned up in d.lang group (my code was a bit messy)

import std.string: find, cmp;
import std.stdio: writefln;

struct Path {
  string thePath;

  int opCmp(Path other) {
    int pos;
    string a, b;

    pos = find(this.thePath, "=");
    if (pos > -1)
      a = this.thePath[0 .. pos];
    else
      a = this.thePath;

    pos = find(other.thePath, "=");
    if (pos > -1)
      b = other.thePath[0 .. pos];
    else
      b = other.thePath;

    return cmp(a, b);
  }
}

void main() {
  string[][Path] contents = [
    Path("/BBB=/other_dir"): ["aa","bb","cc","dd"],
    Path("/AAA"): ["aa","bb","cc","dd"],
    Path("/BB2=/hello") : ["aa","bb","cc","dd"]
                            ];

  foreach (item; contents.keys.sort)
    writefln(item.thePath);
}
November 28, 2008
Small correction, the code I posted works with  D1.0 but not with D2.0. What do I need to change to make it work with D 2.0?

is it better to use D 2 or D 1?

sorry for crossposting, I started my questions on the D group but I was instructed to ask here.


thanks


New Wrote:

> Hello,
> 
> I originally posted this question to the wrong group, I am trying here as suggested.
> 
> I am new with D and am stuck with something I hope somebody can help me with it. I am trying sort an array of paths which can take the two following forms:
> 
> /usr                ---> normal path
> /bin=/other/bin     ---> a symlink
> 
> When I sort these paths, in the case of symlinks I want to ignore the right hand side and I just use the path before the "=" sign.
> 
> The array docs for DMD 2.0, say that can create a structure and create a opCmp function to cutomise the way sort works. I have tried this but calling .sort does not seem to pick-up my custom opCmp.
> 
> Any help would be very appreciated. I am including the code below
> 
> Thanks a lot
> --------------------------------------------------------------------
> Code cleaned up in d.lang group (my code was a bit messy)
> 
> import std.string: find, cmp;
> import std.stdio: writefln;
> 
> struct Path {
>   string thePath;
> 
>   int opCmp(Path other) {
>     int pos;
>     string a, b;
> 
>     pos = find(this.thePath, "=");
>     if (pos > -1)
>       a = this.thePath[0 .. pos];
>     else
>       a = this.thePath;
> 
>     pos = find(other.thePath, "=");
>     if (pos > -1)
>       b = other.thePath[0 .. pos];
>     else
>       b = other.thePath;
> 
>     return cmp(a, b);
>   }
> }
> 
> void main() {
>   string[][Path] contents = [
>     Path("/BBB=/other_dir"): ["aa","bb","cc","dd"],
>     Path("/AAA"): ["aa","bb","cc","dd"],
>     Path("/BB2=/hello") : ["aa","bb","cc","dd"]
>                             ];
> 
>   foreach (item; contents.keys.sort)
>     writefln(item.thePath);
> }

November 28, 2008
just found it accidentally http://d.puremagic.com/issues/show_bug.cgi?id=1309
November 29, 2008
On Fri, 28 Nov 2008 13:58:28 -0500, Kagamin <spam@here.lot> wrote:

>just found it accidentally http://d.puremagic.com/issues/show_bug.cgi?id=1309

Yep, this issue prevents Path.opCmp from being called. The version below works.


import std.string: find, cmp;
import std.stdio: writefln;
import std.algorithm : sort;

struct Path {
    string thePath;

    int opCmp(Path other) {
    	writefln("Path.opCmp");
        int pos;
        string a, b;

        pos = find(this.thePath, "=");
        if (pos > -1)
            a = this.thePath[0 .. pos];
        else
            a = this.thePath;

        pos = find(other.thePath, "=");
        if (pos > -1)
            b = other.thePath[0 .. pos];
        else
            b = other.thePath;

        return cmp(a, b);
    }
}

void main() {
    string[][Path] contents = [
        Path("/002=/other_dir"): ["aa","bb","cc","dd"],
        Path("/001"): ["aa","bb","cc","dd"],
        Path("/002=/hello") : ["aa","bb","cc","dd"]
    ];

    Path[] myPaths = contents.keys.dup;
    //myPaths.sort; // Does not call Path.opCmp
    sort(myPaths); // calls Path.opCmp

    foreach (item; myPaths)
        writefln(item.thePath);
}
December 01, 2008
Thanks very much indeed for your help. The version posted does work. Unfortunately I won't be able to use D for my project, this bug has scared the management, D is still a moving target. I will have to wait until it is more stable.

Cheers.


Gide Nwawudu Wrote:

> On Fri, 28 Nov 2008 13:58:28 -0500, Kagamin <spam@here.lot> wrote:
> 
> >just found it accidentally http://d.puremagic.com/issues/show_bug.cgi?id=1309
> 
> Yep, this issue prevents Path.opCmp from being called. The version below works.
> 
> 
> import std.string: find, cmp;
> import std.stdio: writefln;
> import std.algorithm : sort;
> 
> struct Path {
>     string thePath;
> 
>     int opCmp(Path other) {
>     	writefln("Path.opCmp");
>         int pos;
>         string a, b;
> 
>         pos = find(this.thePath, "=");
>         if (pos > -1)
>             a = this.thePath[0 .. pos];
>         else
>             a = this.thePath;
> 
>         pos = find(other.thePath, "=");
>         if (pos > -1)
>             b = other.thePath[0 .. pos];
>         else
>             b = other.thePath;
> 
>         return cmp(a, b);
>     }
> }
> 
> void main() {
>     string[][Path] contents = [
>         Path("/002=/other_dir"): ["aa","bb","cc","dd"],
>         Path("/001"): ["aa","bb","cc","dd"],
>         Path("/002=/hello") : ["aa","bb","cc","dd"]
>     ];
> 
>     Path[] myPaths = contents.keys.dup;
>     //myPaths.sort; // Does not call Path.opCmp
>     sort(myPaths); // calls Path.opCmp
> 
>     foreach (item; myPaths)
>         writefln(item.thePath);
> }

December 01, 2008
On Mon, Dec 1, 2008 at 7:23 PM, New <here@nowhere.net> wrote:
> Thanks very much indeed for your help. The version posted does work. Unfortunately I won't be able to use D for my project, this bug has scared the management, D is still a moving target. I will have to wait until it is more stable.

D1 is pretty stable, and I'm pretty sure that's what most folks are using these days, actually.

--bb


> Cheers.
>
>
> Gide Nwawudu Wrote:
>
>> On Fri, 28 Nov 2008 13:58:28 -0500, Kagamin <spam@here.lot> wrote:
>>
>> >just found it accidentally http://d.puremagic.com/issues/show_bug.cgi?id=1309
>>
>> Yep, this issue prevents Path.opCmp from being called. The version below works.
>>
>>
>> import std.string: find, cmp;
>> import std.stdio: writefln;
>> import std.algorithm : sort;
>>
>> struct Path {
>>     string thePath;
>>
>>     int opCmp(Path other) {
>>       writefln("Path.opCmp");
>>         int pos;
>>         string a, b;
>>
>>         pos = find(this.thePath, "=");
>>         if (pos > -1)
>>             a = this.thePath[0 .. pos];
>>         else
>>             a = this.thePath;
>>
>>         pos = find(other.thePath, "=");
>>         if (pos > -1)
>>             b = other.thePath[0 .. pos];
>>         else
>>             b = other.thePath;
>>
>>         return cmp(a, b);
>>     }
>> }
>>
>> void main() {
>>     string[][Path] contents = [
>>         Path("/002=/other_dir"): ["aa","bb","cc","dd"],
>>         Path("/001"): ["aa","bb","cc","dd"],
>>         Path("/002=/hello") : ["aa","bb","cc","dd"]
>>     ];
>>
>>     Path[] myPaths = contents.keys.dup;
>>     //myPaths.sort; // Does not call Path.opCmp
>>     sort(myPaths); // calls Path.opCmp
>>
>>     foreach (item; myPaths)
>>         writefln(item.thePath);
>> }
>
>
December 03, 2008
New:
> Thanks very much indeed for your help. The version posted does work. Unfortunately I won't be able to use D for my project, this bug has scared the management, D is still a moving target. I will have to wait until it is more stable.

Tell your management that you have used the D2 language that is in alpha stage still, instead of the D1 that is more stable.

Bye,
bearophile