定制订购数量最多

Mat*_* B. 4 julia

我有一个如下数组:

julia> list = [(x, rand(0:9), rand(0:9)) for x in 1:5]
5-element Array{Tuple{Int64,Int64,Int64},1}:
 (1, 7, 2)
 (2, 1, 3)
 (3, 4, 7)
 (4, 4, 8)
 (5, 8, 3)
Run Code Online (Sandbox Code Playgroud)

我想在该列表中找到第三个值最大的元素。如果我只是这样做maximum(list),它将使用默认(字典顺序)排序,这不是我想要的:

julia> maximum(list)
(5, 8, 3)
Run Code Online (Sandbox Code Playgroud)

by如果对整个列表进行排序,则可以使用自定义转换/谓词:

julia> sort(list, by=x->x[3], rev=true)
5-element Array{Tuple{Int64,Int64,Int64},1}:
 (4, 4, 8)
 (3, 4, 7)
 (2, 1, 3)
 (5, 8, 3)
 (1, 7, 2)
Run Code Online (Sandbox Code Playgroud)

但这做了很多额外的工作-我只需要第一个值-但它似乎maximum不支持by关键字参数:

julia> maximum(list, by=x->x[3])
ERROR: MethodError: no method matching maximum(::Array{Tuple{Int64,Int64,Int64},1}; by=var"#21#22"())
Run Code Online (Sandbox Code Playgroud)

而且,如果我使用“转换”的第一个参数函数,我只会得到第三个值:

julia> maximum(x->x[3], list)
8
Run Code Online (Sandbox Code Playgroud)

我需要整个元素- (4, 4, 8)在这种情况下。我怎样才能做到这一点?

Mat*_* B. 6

虽然maximum不支持by关键字,但它确实支持“变压器”功能。在这种特殊情况下,我们可以找到反转元素的最大值,然后将其反转回来:

julia> reverse(maximum(reverse, list))
(4, 4, 8)
Run Code Online (Sandbox Code Playgroud)

更一般地,您可以使用排序基础结构(及其所有花哨的by转换器和自定义lt比较),而无需实际使用以下命令对整个列表进行排序partialsort

julia> partialsort(list, 1, by=x->x[3], rev=true)
(4, 4, 8)
Run Code Online (Sandbox Code Playgroud)

这虽然效率不高,但功能却要强大得多,并且比对整个事物进行分类要节省很多。带有更大的向量:

julia> using BenchmarkTools

julia> list = [(x, rand(0:9), rand(0:9)) for x in 1:10_000];

julia> @btime reverse(maximum(reverse, $list));
  7.833 ?s (0 allocations: 0 bytes)

julia> @btime partialsort($list, 1, by=x->x[3], rev=true);
  37.772 ?s (3 allocations: 234.48 KiB)

julia> @btime sort($list, by=x->x[3], rev=true);
  339.570 ?s (5 allocations: 351.81 KiB)
Run Code Online (Sandbox Code Playgroud)