Julia SortedSet中的自定义排序

Julia SortedSet中的自定义排序,julia,Julia,在SortedSet的Julia文档中,有一个对“排序对象”的引用,可以在构造函数中使用。我正在做一个项目,需要在一组结构上实现自定义排序。我想用一个函子来做这个,因为我需要更多的状态来进行比较。 下面是我想解决的问题的简化版本。我有两个结构,点和边: struct Point{T<:Real} x::T y::T end struct Edge{T<:Real} first::Point{T} second::Point{T} end struct

在SortedSet的Julia文档中,有一个对“排序对象”的引用,可以在构造函数中使用。我正在做一个项目,需要在一组结构上实现自定义排序。我想用一个函子来做这个,因为我需要更多的状态来进行比较。 下面是我想解决的问题的简化版本。我有两个结构,点和边:

struct Point{T<:Real}
    x::T
    y::T
end
struct Edge{T<:Real}
    first::Point{T}
    second::Point{T}
end

struct Point{T排序基于类型的方法
isless
。例如,如果您有一个类型,您希望在
b
字段中进行排序。例如,您可以

struct Foo{T}
        a::T
        b::T
end

Base.:isless(x::T,y::T) where {T<:Foo} = isless(x.b,y.b)

s=[Foo(1,2),Foo(2,-1)]

res=SortedSet(s)
#SortedSet(Foo[Foo(2, -1), Foo(1, 2)],
#Base.Order.ForwardOrdering())
struct Foo{T}
a::T
b::T
结束

Base.:isless(x::T,y::T),其中{T(x.b,x.a))
b
排序,然后
a
而不必为类型定义
isless

排序对象可以包含字段,您可以将状态存储在那里。这是一个余数排序的示例,它按余数对整数进行排序:

using DataStructures

struct RemainderOrdering <: Base.Order.Ordering
    r::Int
end

import Base.Order.lt
lt(o::RemainderOrdering, a, b) = isless(a % o.r, b % o.r)

SortedSet(RemainderOrdering(3), [1,2,3]) # 3, 1, 2
使用数据结构

struct RemainderOrdering谢谢!这看起来很有希望。关于MWE的观点-我的用例非常复杂,我担心它的细节会分散我的注意力。是的,这个例子让它更清楚。我建议第一种方法,例如定义一个自定义
排序
结构,它包含有利条件,并重载
lt
并将
edge\u排序的逻辑放在那里。这正是我所做的,然后接受了你的回答:)这是我目前使用的临时解决方案。我使用一个全局变量来获取进行比较所需的附加信息。我不喜欢全局变量,这就是我对其他机制感兴趣的原因。我编辑了我的问题,使其更具体-希望我已经澄清了事情。
using DataStructures

struct RemainderOrdering <: Base.Order.Ordering
    r::Int
end

import Base.Order.lt
lt(o::RemainderOrdering, a, b) = isless(a % o.r, b % o.r)

SortedSet(RemainderOrdering(3), [1,2,3]) # 3, 1, 2
using DataStructures
import Base: isless, map

struct Foo # this is your structure
    x::Int
end

struct PrimaryOrdered{T, F} # this is the functor, F is the additional state.
    x::T
end

map(f::Base.Callable, x::T) where {T <: PrimaryOrdered} = T(f(x.x)) # this makes it a functor?
isless(x::PrimaryOrdered{T, F}, y::PrimaryOrdered{T, F}) where {T, F} =
    F(x.x) < F(y.x) # do comparison with your additional state, here I assume it is a closure

const OrderR3 = PrimaryOrdered{Foo, x -> x.x % 3} # a order that order by the remainder by 3

a = OrderR3(Foo(2))
f(x::Foo) = Foo(x.x + 1) # this is a Foo -> Foo
a = map(f, a) # you can map f on a OrderR3 object
a == OrderR3(Foo(33)) # true

a = map(OrderR3 ∘ Foo, [1, 2, 3])

s = SortedSet(a)

map(x->x.x, s) # Foo[3, 1, 2]