Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 27, 2015 On opCmp | ||||
---|---|---|---|---|
| ||||
Is there a more compact way to describe the opCmp function in the following struct struct Hit { size_t count; // number of walkers that found this node NWeight rank; // rank (either minimum distance or maximum strength) auto opCmp(const Hit rhs) const { if (this.count < rhs.count) { return -1; } else if (this.count > rhs.count) { return +1; } else { if (this.rank < rhs.rank) { return -1; } else if (this.rank > rhs.rank) { return +1; } else { return 0; } } } } by reusing something like auto opCmp(const Hit rhs) const { if (this.count < rhs.count) { return -1; } else if (this.count > rhs.count) { return +1; } else { return this.rank.standardOpCmp(rhs.rank) } } |
February 27, 2015 Re: On opCmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Friday, 27 February 2015 at 11:04:51 UTC, Nordlöw wrote:
> Is there a more compact way to describe the opCmp function in the following struct
>
> struct Hit
> {
> size_t count; // number of walkers that found this node
> NWeight rank; // rank (either minimum distance or maximum strength)
>
> auto opCmp(const Hit rhs) const
> {
> if (this.count < rhs.count)
> {
> return -1;
> }
> else if (this.count > rhs.count)
> {
> return +1;
> }
> else
> {
> if (this.rank < rhs.rank)
> {
> return -1;
> }
> else if (this.rank > rhs.rank)
> {
> return +1;
> }
> else
> {
> return 0;
> }
> }
> }
> }
>
> by reusing something like
>
> auto opCmp(const Hit rhs) const
> {
> if (this.count < rhs.count)
> {
> return -1;
> }
> else if (this.count > rhs.count)
> {
> return +1;
> }
> else
> {
> return this.rank.standardOpCmp(rhs.rank)
> }
> }
Two things come to mind:
A) std.algorithm.cmp
----
auto opCmp(const Hit rhs) const
{
import std.algorithm: cmp;
import std.range: only;
if(auto c = cmp(only(count), only(rhs.count)))
{
return c;
}
else /* 'count' values are equal. */
{
return cmp(only(rank), only(rhs.rank));
}
}
----
Maybe there should be a std.algorithm.cmp for non-ranges, too, so that `only` wouldn't be needed here.
B) std.typecons.Tuple has an opCmp that compares all fields in order.
----
auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return tuple(count, rank).opCmp(tuple(rhs.count, rhs.rank));
}
----
This exact behaviour is not documented, though. So I guess it should not be relied on. Maybe the documentation should be more specific. In the meantime, you could duplicate the functionality in a function of your own:
----
import std.typecons: Tuple;
/** Put a proper, specific description here.
*/
int cmpTuples(Types ...)(Tuple!Types a, Tuple!Types b)
{
// copied from std.typecons.Tuple.opCmp
foreach (i, Unused; Types)
{
if (a[i] != b[i])
{
return a[i] < b[i] ? -1 : 1;
}
}
return 0;
}
struct Hit
{
size_t count;
NWeight rank;
auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return cmpTuples(tuple(count, rank), tuple(rhs.count, rhs.rank));
}
}
----
|
February 27, 2015 Re: On opCmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 2/27/15 6:04 AM, "Nordlöw" wrote: > Is there a more compact way to describe the opCmp function in the > following struct > > struct Hit > { > size_t count; // number of walkers that found this node > NWeight rank; // rank (either minimum distance or maximum strength) > > auto opCmp(const Hit rhs) const > { > if (this.count < rhs.count) > { > return -1; > } > else if (this.count > rhs.count) > { > return +1; > } > else > { > if (this.rank < rhs.rank) > { > return -1; > } > else if (this.rank > rhs.rank) > { > return +1; > } > else > { > return 0; > } > } > } > } Hm... what about: return count < rhs.count ? -1 : count > rhs.count ? 1 : rank < rhs.rank ? -1 : rank > rhs.rank; > by reusing something like > > auto opCmp(const Hit rhs) const > { > if (this.count < rhs.count) > { > return -1; > } > else if (this.count > rhs.count) > { > return +1; > } > else > { > return this.rank.standardOpCmp(rhs.rank) > } > } A standard opCmp would be nice. Why wouldn't you use it for count as well? -Steve |
February 27, 2015 Re: On opCmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 02/27/2015 03:04 AM, "Nordlöw" wrote: > Is there a more compact way to describe the opCmp function in the > following struct Please see: http://forum.dlang.org/thread/lnr99a$vvd$1@digitalmars.com#post-lnr99a:24vvd:241:40digitalmars.com Ali |
March 02, 2015 Re: On opCmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 27 February 2015 at 15:00:35 UTC, Steven Schveighoffer wrote:
> Hm... what about:
>
> return count < rhs.count ? -1 : count > rhs.count ? 1 : rank < rhs.rank ? -1 : rank > rhs.rank;
Is this more efficient than my version?
|
March 02, 2015 Re: On opCmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 3/2/15 8:52 AM, "Nordlöw" wrote:
> On Friday, 27 February 2015 at 15:00:35 UTC, Steven Schveighoffer wrote:
>> Hm... what about:
>>
>> return count < rhs.count ? -1 : count > rhs.count ? 1 : rank <
>> rhs.rank ? -1 : rank > rhs.rank;
>
> Is this more efficient than my version?
You said "more compact", not more efficient :)
But I think they are probably the same generated code. I'm not doing anything really different (except for the shortcut for rank > rhs.rank being 1 or 0 based on the conversion to int).
-Steve
|
Copyright © 1999-2021 by the D Language Foundation