Arrays 自定义searchsortedfirst方法
我对Julia lang有点陌生,所以我还在努力阅读Julia文档。这是其中的一部分,我正在寻找解释,特别是加粗部分 Base.Sort.searchsortedfirst-函数 searchsortedfirst(a,x,[by=,][lt=,] [rev=false]) 返回大于或等于x中第一个值的索引, 按照规定的顺序。如果x更大,则返回长度(a)+1 比a中的所有值都高。假设a被分类 我的数组如下所示:Arrays 自定义searchsortedfirst方法,arrays,sorting,vector,julia,Arrays,Sorting,Vector,Julia,我对Julia lang有点陌生,所以我还在努力阅读Julia文档。这是其中的一部分,我正在寻找解释,特别是加粗部分 Base.Sort.searchsortedfirst-函数 searchsortedfirst(a,x,[by=,][lt=,] [rev=false]) 返回大于或等于x中第一个值的索引, 按照规定的顺序。如果x更大,则返回长度(a)+1 比a中的所有值都高。假设a被分类 我的数组如下所示: A = Vector{Record}() 在哪里 type Record
A = Vector{Record}()
在哪里
type Record
y::Int64
value::Float64
end
现在我的问题来了。我想对我的数组调用上述方法,并获取记录,其中给定的x等于该记录中的y(Record.y==x)。我想我必须写“by”transfrom或“lt”比较器?或者两者都有
欢迎提供任何帮助:)您只需定义一个自定义的小于操作,并通过
lt
关键字参数将其交给searchsortedfirst
:
julia> type Record
y::Int64
value::Float64
end
julia> A = Vector{Record}()
0-element Array{Record,1}
julia> push!(A, Record(3,3.0))
1-element Array{Record,1}:
Record(3, 3.0)
julia> push!(A, Record(4,3.0))
2-element Array{Record,1}:
Record(3, 3.0)
Record(4, 3.0)
julia> push!(A, Record(5,3.0))
3-element Array{Record,1}:
Record(3, 3.0)
Record(4, 3.0)
Record(5, 3.0)
julia> searchsortedfirst(A, 4, lt=(r,x)->r.y<x)
2
julia>类型记录
y::Int64
值::Float64
结束
julia>A=Vector{Record}()
0元素数组{Record,1}
朱莉娅>推!(A,记录(3,3.0))
一元数组{记录,1}:
记录(3,3.0)
朱莉娅>推!(A,记录(4,3.0))
二元数组{记录,1}:
记录(3,3.0)
记录(4,3.0)
朱莉娅>推!(A,记录(5,3.0))
三元素数组{记录,1}:
记录(3,3.0)
记录(4,3.0)
记录(5,3.0)
julia>searchsortedfirst(A,4,lt=(r,x)->r、 yr.y@crstnbr为一次性使用searchsortedfirst
提供了一个完美的答案。我认为值得补充的是,还有一个更持久的解决方案。如果您的类型记录
表现出自然的顺序,那么只需将Base.isless
和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
struct MyType;x::Float64;end#定义我自己的某种类型
yvec=MyType.(sort!(randn(10))#构建我的类型的随机向量
yval=MyType(0.0)#构建MyType的值
searchsortedfirst(yvec,yval)#错误:使用searchsortedfirst会引发MethodError,因为julia不知道如何订购MyType
Base.isless(y1::MyType,y2::MyType)::Bool=y1.x
有几点值得注意:
1)在重载isless
和isequal
的步骤中,我用Base作为方法定义的序言。
。这是因为isless
和isequal
函数最初是在Base
中定义的,其中Base
指每次启动julia时自动加载的核心julia包。通过使用Base.
,我可以确保我的新方法被添加到这两个函数的当前方法集中,而不是替换它们。注意,我也可以通过省略Base来实现这一点。
但在导入Base:isless,isequal之前包含一行。就个人而言,我更喜欢上面提到的方式(对于过于迂腐的人,你也可以两者兼而有之)
2)我可以定义isless
和isequal
任何我想要的。它是我的类型和方法扩展。因此,您可以选择任何您认为是您的新类型的自然顺序
3)操作符
,实际上都只是在引擎盖下调用isless
和isequal
,因此所有这些操作符现在都将与您的新类型一起工作,例如MyType(1.0)>MyType(2.0)
返回false
4)任何使用上述比较运算符的julia函数现在都可以与您的新类型一起使用,只要该函数是参数化定义的(基本上Base
中的所有函数都是参数化定义的)。听起来像是find(r->r.y==x,A)
对我来说?@crstnbr获得了排序数组,所以如果函数小于O(n)就很酷了. 谢谢你的建议,tho:)那正是我想要的。谢谢你的解释:)回答得好。我打算在这里添加一条评论,您也可以扩展Base.isless
和Base.isequal
,但它最后有点长,所以我把它作为第二个答案来写。但我认为这两种方法都很“朱利安”。哦,这很有帮助!所以基本上你要做的就是在这个“基类”中重载一个方法,我猜?你能告诉我更多关于它的用法吗?或者链接一些网站?感谢您的努力澄清@Kennsy我已经对我的答案进行了重大修改,加入了一些新的信息,希望能回答你的问题。如果还有什么需要澄清的,请告诉我。