Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
June 15, 2014 How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
I am new to D so I am probably not using the right terminology but here is a piece of C++ code (not complete) that I would like to translate to idiomatic D. I have defined a function object that I pass to std::sort to std:map as follows: enum class SortOrder{ ASC, DESC }; typedef std::vector<boost::variant> DataRow; // this is one row of data in a 2D array. Data items are variants but this is not very important typedef std::vector<DataRow> Data; // this is simply a 2D array Data the_data; // the function object is here. I don't want a lamda because I want to be able to call this from multiple places class MyCompare { public: explicit MyCompare(int column, SortOrder order) : m_column(column), m_order(order) {} bool operator()(const DataRow& lhs, const DataRow& rhs) { switch (m_order) { case SortOrder::ASC: return lhs[m_column] < rhs[m_column]; case SortOrder::DESC: return rhs[m_column] < lhs[m_column]; } } private: int m_column; SortOrder m_order; }; example 1: int column = 3; SortOrder order = DESC; std::sort(the_data.begin(), the_data.end(), MyCompare(column, order)); example 2: MyCompare comp(column, order); std::map<DataRow, Data, MyCompare> mp( comp ); What is the equivalent idiomatic D? |
June 16, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to belkin | You can pass anything to the sort function that's callable, including an object: struct MyCompare { SortOrder order; int column; bool opCall(const ref DataRow lhs, const ref DataRow rhs) { return order == SortOrder.ASC ? lhs[column] < rhs[column] : rhs[column] < lhs[column]; } } import std.algorithm; MyCompare cmp(SortOrder.ASC, 10); my_columns.sort!cmp; (Untested.) |
June 16, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Monday, 16 June 2014 at 09:24:22 UTC, Marc Schütz wrote:
> You can pass anything to the sort function that's callable, including an object:
>
> struct MyCompare {
> SortOrder order;
> int column;
> bool opCall(const ref DataRow lhs, const ref DataRow rhs) {
> return order == SortOrder.ASC ?
> lhs[column] < rhs[column] :
> rhs[column] < lhs[column];
> }
> }
>
> import std.algorithm;
> MyCompare cmp(SortOrder.ASC, 10);
> my_columns.sort!cmp;
>
> (Untested.)
That works, but it's not very idiomatic. Well, I have never seen a C++ style "functor" used in D template is what I'm saying. I don't know if that's good or bad. A more idiomatic approach would be to simply pass a delegate to your function.
This can either be as a pointer to member function:
struct MyCompare {
SortOrder order;
int column;
bool compare(const ref DataRow lhs, const ref DataRow rhs)
{
return order == SortOrder.ASC ?
lhs[column] < rhs[column] :
rhs[column] < lhs[column];
}
}
import std.algorithm;
MyCompare cmp(SortOrder.ASC, 10);
auto dg = &cmp.compare;
my_columns.sort!dg;
Or, more generally, via a lambda, or a function with state:
import std.algorithm;
column = 10;
bool compare(const ref DataRow lhs, const ref DataRow rhs)
{
return order == SortOrder.ASC ?
lhs[column] < rhs[column] :
rhs[column] < lhs[column];
}
}
my_columns.sort!compare;
|
June 17, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote:
> MyCompare cmp(SortOrder.ASC, 10);
This syntax is not valid D.
It should be:
auto cmp = MyCompare(SortOrder,ASC, 10);
|
June 17, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Tuesday, 17 June 2014 at 04:32:20 UTC, Jakob Ovrum wrote:
> On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote:
>> MyCompare cmp(SortOrder.ASC, 10);
>
> This syntax is not valid D.
>
> It should be:
>
> auto cmp = MyCompare(SortOrder,ASC, 10);
Sorry, that first comma is a typo and should be a dot.
auto cmp = MyCompare(SortOrder.ASC, 10);
|
June 17, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Tuesday, 17 June 2014 at 04:32:20 UTC, Jakob Ovrum wrote:
> On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote:
>> MyCompare cmp(SortOrder.ASC, 10);
>
> This syntax is not valid D.
>
> It should be:
>
> auto cmp = MyCompare(SortOrder,ASC, 10);
Well, techincally, the *syntax* is valid. If "MyCompare" contains a constructor, it's legit code to boot. It's part of the uniform initialization syntax, and it's what allows things like:
BigInt b = 5;
or
BigInt b(5);
THAT said, yeah, the MyCompare I posted did not contain a constructor. SO my code was wrong, guilty as charged.
|
June 17, 2014 Re: How to define and use a custom comparison function | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Tuesday, 17 June 2014 at 07:53:51 UTC, monarch_dodra wrote:
> On Tuesday, 17 June 2014 at 04:32:20 UTC, Jakob Ovrum wrote:
>> On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote:
>>> MyCompare cmp(SortOrder.ASC, 10);
>>
>> This syntax is not valid D.
>>
>> It should be:
>>
>> auto cmp = MyCompare(SortOrder,ASC, 10);
>
> Well, techincally, the *syntax* is valid. If "MyCompare" contains a constructor, it's legit code to boot. It's part of the uniform initialization syntax, and it's what allows things like:
>
> BigInt b = 5;
> or
> BigInt b(5);
>
> THAT said, yeah, the MyCompare I posted did not contain a constructor. SO my code was wrong, guilty as charged.
Since when is that syntax valid? Is there somewhere it is documented?
|
Copyright © 1999-2021 by the D Language Foundation