我有一个如下所示的数组:
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)
我想在该列表中找到第三个值最大的元素。如果我只是做
maximum(list)
,它使用默认(词典)排序,这不是我想要的:julia> maximum(list)
(5, 8, 3)
我可以使用自定义
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)
但这做了很多额外的工作——我需要的只是第一个值——但它似乎是
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"())
如果我使用“转换”第一个参数函数,我只会得到第三个值:
julia> maximum(x->x[3], list)
8
我想要整个元素 —
(4, 4, 8)
在这种情况下。我怎样才能做到这一点?
最佳答案
虽然 maximum
不支持by
关键字,它确实支持“变压器”功能。在这种特殊情况下,我们可以找到反转元素的最大值,然后将其反转回来:
julia> reverse(maximum(reverse, list))
(4, 4, 8)
更一般地说,您可以使用排序基础设施(以及所有花哨的
by
转换器和自定义 lt
比较),而无需实际使用 partialsort
对整个列表进行排序。 :julia> partialsort(list, 1, by=x->x[3], rev=true)
(4, 4, 8)
这不是那么有效,但它的功能要强大得多 - 并且它比对整个事物进行排序节省了很多。使用更大的向量:
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)
关于julia - 自定义订购的最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58738601/