自定义 searchsortedfirst 方法

J.*_*nsy 3 arrays sorting vector julia

我对 Julia lang 有点陌生,所以我仍在努力阅读 Julia 文档。这是其中的一部分,我正在寻找特别是粗体部分的解释。

Base.Sort.searchsortedfirst — 函数。

searchsortedfirst(a, x, [by=,] [lt=,] [rev=false])

根据指定的顺序返回大于或等于 x 的第一个值的索引。如果 x 大于 a 中的所有值,则返回 length(a)+1。假设 a 已排序。

网站

我的数组如下所示:

A = Vector{Record}()
Run Code Online (Sandbox Code Playgroud)

在哪里

type Record
     y::Int64
     value::Float64
end
Run Code Online (Sandbox Code Playgroud)

现在这是我的问题。我想在我的数组上调用上述方法并获取记录,其中给定的 x 等于此记录中的 y (Record.y == x)。猜猜我必须写 'by' transfrom 或 'lt' 比较器?或两者?

任何帮助都会得到认可:)

Col*_*ers 5

@crstnbr 为一次性使用searchsortedfirst. 我认为值得补充的是,还有一个更永久的解决方案。如果您的类型Record表现出自然排序,那么只需将Base.islessand扩展Base.isequal到您的新类型。以下示例代码显示了它如何适用于您可能定义的某些新类型:

struct MyType ; x::Float64 ; end  #Define some type of my own
yvec = MyType.(sort!(randn(10)))  #Build a random vector of my type
yval = MyType(0.0)                #Build a value of my type
searchsortedfirst(yvec, yval)     #ERROR: this use of searchsortedfirst will throw a MethodError since julia doesn't know how to order MyType
Base.isless(y1::MyType, y2::MyType)::Bool = y1.x < y2.x   #Extend (aka overload) isless so it is defined for the new type
Base.isequal(y1::MyType, y2::MyType)::Bool = y1.x == y2.x #Ditto for isequal
searchsortedfirst(yvec, yval)     #Now this line works
Run Code Online (Sandbox Code Playgroud)

值得注意的几点:

1)在重载islessand的步骤中isequal,我在方法定义前加上Base.。这是因为islessisequal函数最初是在中定义的Base,这里Base指的是每次启动 julia 时自动加载的核心 julia 包。通过以 开头Base.,我确保将我的新方法添加到这两个函数的当前方法集中,而不是替换它们。请注意,我也可以通过Base.import Base: isless, isequal. 就个人而言,我更喜欢上面的方法(对于过于迂腐的人,您也可以两者都做)。

2)我可以定义islessisequal但是我想要。这是我的类型和我的方法扩展。因此,您可以选择任何您认为适合新类型的自然顺序。

3)运营商<<=, ==, >=, >, 实际上只是调用islessisequal隐藏,所以所有这些运算符现在都可以与您的新类型一起使用,例如MyType(1.0) > MyType(2.0)返回false

4)任何使用上述比较运算符的 julia 函数现在都可以与您的新类型一起使用,只要该函数是参数化定义的(几乎所有内容Base都是如此)。